• 1. 网络程序设计
  • 2. 本章内容网络基础 TCP/IP协议 IP地址 URL and URLConnection Socket通信 TCP / UDP
  • 3. 网络基础概念什么是计算机网络: 把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。 计算机网络的主要功能 资源共享 信息传输与集中处理 均衡负荷与分布处理 综合信息服务 (www/综合业务数字网络 ISDN)
  • 4. 网络通信协议及接口什么是网络通信协议 计算机网络中实现通信必须有一些约定即通信协议,对速率、传输代码、代码结构、传 输控制步骤、出错控制等制定标准。 网络通信接口 为了使两个结点之间能进行对话,必须在它们之间建立通信工具(即接口),使彼此之间 能进行信息交换。接口包括两部分: 硬件装置: 实现结点之间的信息传送 软件装置: 规定双方进行通信的约定协议
  • 5. 通信协议分层的思想为什么要分层 由于结点之间联系很复杂,在制定协议时,把复杂成份分解成 一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。 通信协议的分层规定 把用户应用程序作为最高 层,把物理通信线路作为最低层,将其间的协议处理分为若干层,规定每层处理的任务,也规定每层的接口标准。 第 5 层第 4 层第 3 层第 1 层第 2 层第 5 层第 4 层第 3 层第 1 层第 2 层第1层协议第3层协议第2层协议第4层协议第5层协议物 理 介 质
  • 6. OSI参考模型表 示 层应 用 层会 话 层网 络 层传 输 层数据链路层物 理 层TCP/IP参考模型参考模型Link (Device driver, …)Network (IP, ICMP, ARP, RARP…)Transport (TCP, UDP…)Application (HTTP, FTP, TELNET, POP3, SMPT…)
  • 7. 传输层 数据链路层物理层 网络层 上层数据上层数据传输层控制信息数据网络层控制信息数据逻辑链路子层控制信息0101110101001000010数据表示层应用层会话层SegmentPacketBitsFrameFCSFCS数据封装
  • 8. 上层数据逻辑链路控制子层控制信息+网络层控制信息+传输层控制信息+上层数据媒体访问控制子层控制信息网络层控制信息+传输层控制信息+上层数据逻辑链路子层控制信息传输层控制信息+上层数据网络层控制信息上层数据传输层控制信息0101110101001000010传输层 数据链路层物理层 网络层 表示层应用层会话层 数据拆封
  • 9. IP协议IP (Internet Protocol)协议是网际层的主要协议,支持网间互连的数据报通信。它提供主要功能有: 无连接数据报传送 数据报路由选择和差错控制
  • 10. TCP协议和UDP协议TCP(transmission control protocol) 是专门设计用于在不可靠的因特网上提供可靠的、端到端的字节流通信的协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。 UDP(user data protocol) UDP向应用程序提供了一种发送封装的原始IP数据报的方法,并且发送时无需建立连接。是一种不可靠的连接 .
  • 11. URL 在WWW上,每一信息资源都有统一的且唯一的地址,该地址就叫URL(Uniform Resource Locator),它是WWW的统一资源定位标志。URL由4部分组成:协议 、存放资源的主机域名、资源文件名和端口号。如果未指定该端口号,则使用协议默认的端口。例如,http 协议的默认端口为 80。
  • 12. URL类构造方法类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。 URL类提供用于创建URL对象的构造方法: (1)public URL(String str) 它是使用URL的字符串来创建URL对象。 (2)public URL(String protocol,String host,String file) 这个构造方法中指定了协议名“protocol”、主机名“host”、文件名“file”,端口使用缺省值。 (3)public URL(String protocol,String host,String port,String file) 这个构造方法与(2)构造方法中多了一个端口号“port”。 (4)public URL(URL content,String str)方法 这个构造方法是给出一个相对于content的路径偏移量。
  • 13. URL类方法URL类功能说明int getPort()获得端口号,如果端口没有设置,则返回-1String getProtocol()获得协议名,如果协议没有设置,则返回nullString getHost()获得主机名,如果主机没有设置,则返回nullString getFile()获得文件名,如果文件没有设置,则返回nullBoolean equals(Object obj) 与指定的URL对象obj进行比较,如果相同返回true,否则返回falsefinal InputStream OpenStream()获得一个输入流。若获取失败,则抛出一个java.io.Exception 异常String toString()将此URL对象转换为字符串的形式
  • 14. Java实例——URLimport java.net.*; import java.io.*; public class UrlSite { public static void main(String args[]) { if (args.length < 1) { System.out.println("没有给出URL"); System.exit(1); } else { for (int i = 0; i < args.length; i++) { try { urlSite(args[i]); } catch (MalformedURLException e) { System.out.println("URL格式不正确: " + args[i]); e.printStackTrace(); } catch (IOException e) { System.out.println("URL文件打开错误" + args[i]); }}} }
  • 15. Java实例——(续) private static void urlSite(String urlname) throws MalformedURLException,IOException { String s; URL url = null; BufferedReader in = null; try { url = new URL(urlname); in = new BufferedReader(new I InputStreamReader(url.openStream())); while ((s = in.readLine()) != null) { System.out.println(s); } } finally { try { in.close(); } catch (IOException e) {e.printStackTrace();} } } }
  • 16. URLConnection类 使用URLConnect类不仅可以使用getInputStream()方法获得URL节点的信息,而且还可以采用getOutoutSream()方法向URL节点处传输数据,这样在本机与URL节点处形成了一个数据流通道。数据的输入和输出必须遵循HTTP协议中规定的格式,事实上,在建立URLConnection类的对象的同时就已经在本机和URL节点之上建立了一条HTTP通道。
  • 17. Java实例——URLConnectionimport java.io.*; import java.net.*; import java.util.*; public class URLConnectionTest{ public static void main(String[] args){ try{ String urlName; if (args.length > 0) urlName = args[0]; else urlName = "http://java.sun.com"; // step 1. Create a URL URL url = new URL(urlName); URLConnection connection = url.openConnection(); // step 2. Connect to the server connection.connect(); // print header fields int n = 1; String key;
  • 18. Java实例——(续) while ((key = connection.getHeaderFieldKey(n)) != null){ String value = connection.getHeaderField(n); System.out.println(key + ": " + value); n++; } // print convenience functions System.out.println("----------"); System.out.println("getContentType: "+ connection.getContentType()); System.out.println("getContentLength: "+ connection.getContentLength()); System.out.println("getContentEncoding: "+ connection.getContentEncoding()); System.out.println("getDate: "+ connection.getDate()); System.out.println("getExpiration: "+ connection.getExpiration()); System.out.println("getLastModifed: "+ connection.getLastModified()); System.out.println("----------");
  • 19. Java实例——(续) // step 3 and 4. Get an InputStream and encapsulate it BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); // print first ten lines of contents String line = null; n = 1; // step 5. Read info from the stream while ((line = in.readLine()) != null && n <= 10){ System.out.println(line); n++; } if (line != null) System.out.println(". . ."); } catch (IOException exception){ exception.printStackTrace(); } } }
  • 20. Socket通信两个Java应用程序可通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket。 Socket通常用来实现client-server连接。 java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连接的client和server端 建立连接时所需的寻址信息为远程计算机的IP地址和端口号(Port number) A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sentServerClientportConnection requestServerClientportConnectionport
  • 21. Socket 通信模型ServerServerSocket s(port #)s.accept() / 等待连接Socket 对象OutputStreamInputStreamsocket.close()ClientSocket (host, port #) (Attempt to connect)OutputStreamInputStreamsocket.close()
  • 22. Typical Steps to Write a Socket ServerCreate a serversocket Accept a connection request from a client and return a new socket Get input stream / output stream from the accpeted socket Encapsulate raw input stream /output stream to high level streams according to data type (optional) Receive/send message from/to streams Release resources ServerSocket(port)Socket.getInputStream()/ Socket.getOuputStream()DataInputStream(InputStream) / DataOutputStream(OutputStream) (for example, optional)(XXX)InputStream.read() / (XXX)OutputStream.write()(XXX)InputStream.close() / (XXX)OutputStream.close() Socket.close(), ServerSocket.close()Socket s = ServerSocket.accept()
  • 23. A ServerSocket Sample—Daytime ServerThe daytime server based on TCP listens on port 13, it accepts connection request from a client and generate a new socket. Get a OutputStream from the new socket and encapsulate it to a PrintWriter Prepare the daytime string and write it to the PrintWriter Close resources including PrintWriter, Socket and ServerSocket
  • 24. ServerSocketimport java.net.*; import java.io.*; import java.util.*; import java.text.SimpleDateFormat; public class DaytimeServer { public static void main(String[] args) { ServerSocket ss = null; Socket s = null; PrintWriter pw = null; try { // step 1. Create a listen socket ss = new ServerSocket(8899); // step 2. Accept connection request from a client s = ss.accept(); // step 3. Get a OutputStream from the socket OutputStream os = s.getOutputStream(); // step 4. Encapsulate os to a PrintWriter pw = new PrintWriter(os); SimpleDateFormat format = new SimpleDateFormat ("yyyy-MM-ddhh:mm:ss");
  • 25. ServerSocket——(续) String dtStr = format.format(new Date()); // step 5. Write daytime string to the client pw.println(dtStr); } catch (IOException e) { // handle exception e.printStackTrace(); } finally { // step 6. Release resources pw.close(); try { s.close(); } catch (IOException e) { } try { ss.close(); } catch (IOException e) { } } } }
  • 26. Important Mehods in java.net.ServerSocketServerSocket<> +ServerSocket(port : int) +ServerSocket(port : int, backlog : int) +accept() : Socket +close(): void +setSoTimeout(timeout : int) : void
  • 27. Steps to Write a Socket ClientCreate a socket Get input stream and/or output stream from the connected socket Encapsulate raw input stream /output stream to high level streams according to data type (optional) Receive/send message from/to streams Release resources Socket(host, port)Socket.getInputStream()/ Socket.getOuputStream()DataInputStream(InputStream) / DataOutputStream(OutputStream) (for example, optional)(XXX)InputStream.read() / (XXX)OutputStream.write()(XXX)InputStream.close() / (XXX)OutputStream.close() Socket.close()
  • 28. A Socket Client—Getting Daytime from A ServerMost unix systems provide daytime service based on TCP protocol on port 13. The daytime server accept a client connection request and send back the daytime string followed by a new line character to the client, then close the connection. So, we create a socket to connect to the daytime server, encapsulate the input stream got from Socket to a BufferedReader, read one line of string from the BufferedReader and display the string, then release all resources.
  • 29. A Socket Client—Getting Daytime from A Server(Cont.)import java.net.Socket; import java.io.InputStream; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.IOException; public class TimeClient { public static void main(String[] args) { // The program needs a command line argment to specify the name // or IP address of a daytime server if (args.length != 1) { System.out.println("Usage: " + "java " +TimeClient.class.getName()+ " timeServerName"); System.exit(1); }
  • 30. A Socket Client—Getting Daytime from A Server(Cont.) Socket s = null; BufferedReader br = null; // Encapsulate the InputStream got from s try { // step 1. Create a socket s = new Socket(args[0], 8899); // step 2. Get an InputStream from the socket InputStream is = s.getInputStream(); // step 3. Encapsulate the InputStream to a BufferedReader br = new BufferedReader(new InputStreamReader(is)); // step 4. Read the daytime string from the reader String str = br.readLine(); System.out.println(str);
  • 31. A Socket Client—Getting Daytime from A Server(Cont.) } catch (IOException e) { // handle exception e.printStackTrace(); } finally { // step 5. Release resources try { br.close(); } catch (IOException e) { } try { s.close(); } catch (IOException e) { } } } }
  • 32. Important methods in java.net.SocketSocket<> +Socket() +Socket(host: String, port: int) +Socket(host: String, port: int, localAddr: InetAddress, localPort : int) +getInputStream() : InputStream +getOutputStream() : OutputStream +close(): void +setSoTimeout(timeout : int) : void +setKeepAlive(on: boolean) : void +setSoLinger(on: boolean, linger: int) void
  • 33. Steps to Handle Concurrency in Socket Server ProgrammingMultiple clients access a server at the same time, each client needs a connection, so one thread per connection Create a server socket Accept a connection request from a client and return a new socket, then generate a service thread (repeat) In thread get input stream / output stream from the accpeted socket In thread encapsulate raw input stream /output stream to high level streams according to data type (optional) In thread receive/send message from/to streams In thread Release resources ThreadSeverSocket(port)Socket.getInputStream()/ Socket.getOuputStream()DataInputStream(InputStream) / DataOutputStream(OutputStream) (for example, optional)(XXX)InputStream.read() / (XXX)OutputStream.write()(XXX)InputStream.close() / (XXX)OutputStream.close() Socket.close(), ServerSocket.close()Socket s = SeverSocket.accept()
  • 34. A Multi-Thread ServerSocket Sample— Reversioned Daytime ServerThe daytime server based on TCP listens on port 13, it accepts connection request from a client and generate a new socket. Fork a new thread and pass the new socket to the thread In the thread get a OutputStream from the new socket and encapsulate it to a PrintWriter In the thread prepare the daytime string and write it to the PrintWriter In the thread close resources including PrintWriter, Socket
  • 35. ThreadServerimport java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.util.Date; public class ThreadServer extends Thread { private Socket s; public ThreadServer(Socket s) { this.s = s; } public void run() { PrintWriter pw = null; try { // step 1. Get a OutputStream from the socket OutputStream os = s.getOutputStream(); // step 2. Encapsulate os to a PrintWriter pw = new PrintWriter(os);
  • 36. ThreadServer // prepare daytime string Date d = new Date(); String dtStr = d.toString(); // step 3. Write daytime string to the client pw.println(dtStr); } catch (IOException e) { e.printStackTrace(); } finally { // step 4. Release resource pw.close(); try { s.close(); } catch (IOException e) { e.printStackTrace(); } } } }
  • 37. DaytimeServer2import java.net.ServerSocket; import java.net.Socket; import java.io.IOException; public class DaytimeServer2 { public static void main(String[] args) { ServerSocket ss = null; Socket s = null; // store the return from ss.accept() try { // step 1. Create a listen socket ss = new ServerSocket(13); // step 2. Accept connection request from a client while (true) { s = ss.accept(); new ThreadServer(s).start(); } } catch (IOException e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { } } } }
  • 38. UDP UDP通信是一种无连接的数据报通信,采用数据报通信协议UDP(User Datagram Protocol)。按照这个协议,两个系统在进行通信时,不要建立连接,优点是它发送数据的速度很快,而缺点是数据较易丢失,例如我们使用的红外线数据传输就是采用UDP的传输协议。 Connectionless protocol Not reliable transfer DatagramSocket and DatagramPacket support Java UDP
  • 39. java.net.DatagramPacket数据报包用来实现无连接包投递服务。 每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。 Constructors DatagramPacket(byte[] buf, int length): 构造 DatagramPacket,用来接收长度为 length 的数据包, length 参数必须小于或等于 buf.length DatagramPacket(byte[] buf, int length, InetAddress address, int port):构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。length 参数必须小于或等于 buf.length。 Methods getAddress()/getSockAddress()/getPort() setAddress()/setSockAddress()/setPort()
  • 40. java.net.DatagramSocketA datagram socket is the sending or receiving point for a packet delivery service Constructors DatagramSocket(int port) Methods connect()/close() receive()/send()
  • 41. Typical Steps to Write a UDP ServerCreate a DatagramSocket bound to a port Prepare a datagram packet to receive message from clients Receive message on datagram socket and put the message into datagram packet Get the info of the client protocol address Prepare a datagram packet which includes message sent back to the client Send datagram packet to the client Repeat 2 - 6 DatagramSocket(port)DatagramSocket. receive(DatagramPacket)DatagramPacket.getAddress(); DatagramPacket.getPort()DatagramPacket(buffer, length, clientAddress, clientPort);DatagramSocket.send (Datagrampacket)DatagramPacket(buffer, len);
  • 42. A UDP Server Sample—Daytime ServerThe daytime server based on UDP bound to port 13, it must receive message from a client first because it has no sense of the protocol address info of a client So, a client can send any message to the server because the server ignore it The server get address info from the inbound datagram packet Prepare the daytime string and put it in the outbound datagram packet Send the outbound datagram packet from the datagram socket to the client
  • 43. UDPDaytimeServerimport java.io.*; import java.net.*; import java.util.*; public class UDPDaytimeServer { public static void main(String args[]) { UDPDaytimeServer udpServer = new UDPDaytimeServer(); try { udpServer.go(); } catch (IOException e) { System.out.println("IOException occured with socket."); System.out.println(e); System.exit(1); } } // This method retrieves the current time on the server public byte[] getTime() { Date d = new Date(); return d.toString().getBytes(); }
  • 44. UDPDaytimeServer // Main server loop. public void go() throws IOException { DatagramSocket datagramSocket; DatagramPacket inDataPacket; // Datagram packet from the client DatagramPacket outDataPacket; // Datagram packet to the client InetAddress clientAddress; // Client return address int clientPort; // Client return port byte[] msg = new byte[10]; // Incoming data buffer. Ignored. byte[] time; // Stores retrieved time // Allocate a socket to man port 13 for requests. datagramSocket = new DatagramSocket(13); System.out.println("UDP server active on port 13"); // Loop forever while (true) {
  • 45. UDPDaytimeServer // Set up receiver packet. Data will be ignored. inDataPacket = new DatagramPacket(msg, msg.length); // Get the message. datagramSocket.receive(inDataPacket); // Retrieve return address information, including InetAddress // and port from the datagram packet just recieved. clientAddress = inDataPacket.getAddress(); clientPort = inDataPacket.getPort(); // Get the current time. time = getTime(); // set up a datagram to be sent to the client using the // current time, the client address and port outDataPacket = new DatagramPacket(time, time.length, clientAddress, clientPort); // finally send the packet datagramSocket.send(outDataPacket); } } }
  • 46. Typical Steps to Write a UDP ClientCreate a datagram socket Prepare a datagram packet which includes message and the server protocol address info Send the datagram packet to the server from the datagram socket Prepare a datagram socket which includes a buffer and its length to receive response from the server Receive message from the datagram socket and put the message into the datagram packet prepared in the last step Close the datagram socketDatagramSocket()DatagramSocket. send(DatagramPacket)DatagramPacket(buffer, length)DatagramSocket.receive (Datagrampacket)DatagramSocket.close()DatagramPacket(buffer, len, Serveraddr, serverport);
  • 47. A UDP Client Sample— Daytime ClientThe daytime client based on UDP get the daytime string from a udp daytime server bound to port 13 First the client prepare a outbound datagram packet which includes the server protocol address info and a buffer Send the outbound datagram packet to the server Prepare an inbound datagram packet in which there is a buffer to holds daytime string sent back from the server Receive message from the datagram socket and put the message into the inboud datagram packet
  • 48. UDPClientimport java.io.*; import java.net.*; public class UDPClient { public static void main(String args[]) { UDPClient udpClient = new UDPClient(); try { udpClient.go(); } catch (Exception e) { System.out.println("Exception occured with socket."); System.out.println(e); System.exit(1); } } public void go() throws IOException, UnknownHostException { DatagramSocket datagramSocket; DatagramPacket outDataPacket; // Datagram packet to the server DatagramPacket inDataPacket; // Datagram packet from the server InetAddress serverAddress; // Server host address byte[] msg = new byte[100]; // Buffer space.
  • 49. UDPClient String receivedMsg; // Received message in String form. // Allocate a socket by which messages are sent and received. datagramSocket = new DatagramSocket(); // Server is running on this same machine for this example. // This method can throw an UnknownHostException. serverAddress = InetAddress.getLocalHost(); // Set up a datagram request to be sent to the server. // Send to port 13 outDataPacket = new DatagramPacket(msg, 1, serverAddress, 13); // Make the request to the server. datagramSocket.send(outDataPacket); // Set up a datagram packet to receive server's response. inDataPacket = new DatagramPacket(msg, msg.length); // Receive the time data from the server datagramSocket.receive(inDataPacket); // Print the data received from the server ReceivedMsg = new String(inDataPacket.getData(), 0, inDataPacket.getLength()); System.out.println(receivedMsg); // close the socket DatagramSocket.close(); }}