1. TCP/IP协议栈
与OSI参考模型不同,TCP/IP协议栈共有4层,其中网络接口层对应OSI中的物理层和数据链路层,应用层对应OSI中的应用层、表示层和会话层。
在网络接口层的主要协议有:ARP、RARP等。ARP协议主要功能是根据IP地址获取物理地址,RARP协议则反之。
网络层的主要协议有:IP、路由协议(RIP、OSPF、BGP等)。IP协议为网络上的每台主机编号,在此基础上才有路由协议,因此路由协议是基于IP协议的。
传输层的主要协议有:TCP、UDP。传输层有端口号的概念,端口号是指TCP或UDP协议能根据端口号找到接受数据包的进程。(也就是说一个TCPServer和一个UDPServer可以绑定同一个端口,详细解释参看第2节)
应用层协议主要有:HTTP、FTP、SMTP等。
2. “协议号+端口号”唯一确定了接收数据包的进程
协议号:协议号是存在于IP数据报的首部的20字节的固定部分,占有8bit。该字段是指出此数据报所携带的是数据是使用何种协议,以便目的主机的IP层知道将数据部分上交给哪个传输层协议(TCP/UDP等)。
端口号:端口号存在于TCP/UDP报文的首部。
目的主机收到数据报后,IP协议会将解析到协议号,并据此将数据上送给相应的传输层协议;传输层协议收到数据并解析,获得端口号,并据此将数据上送给相应的接受数据报的进程。
从上述过程可知,端口号是按照传输层协议号划分了“命名空间”的,因此,同一主机可以同时运行绑定同一端口号的TCP Socket(java中对应ServerSocket、Socket)和UDP Socket(java中对应DatagramSocket)而不发生冲突。
3. 附件
测试使用的代码:
TCPClient.java
1 package socket; 2 3 import java.io.*; 4 import java.net.*; 5 import java.util.Date; 6 7 public class TCPClient { 8 9 /** 10 * @param args 11 */ 12 public static void main(String[] args) { 13 // TODO Auto-generated method stub 14 try { 15 System.out.println(new Date()); 16 InetAddress remoteAddress = InetAddress.getByName("22.11.143.60"); 17 // InetAddress localAddress = InetAddress.getByName("127.0.0.1"); 18 // Socket socket = new Socket(remoteAddress, 1287, localAddress, 1288); 19 // Socket socket = new Socket(remoteAddress, 1287); 20 Socket socket = new Socket (); 21 socket.connect(new InetSocketAddress(remoteAddress,1287), 1000); 22 socket.setSoTimeout(110000); 23 System.out.println(new Date()); 24 PrintWriter os = new PrintWriter(socket.getOutputStream()); 25 BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream())); 26 String msg = "hello"; 27 os.println(msg); 28 os.flush(); 29 System.out.println("Client: " + msg); 30 // Thread.sleep(1000); 31 System.out.println("Server: " + is.readLine()); 32 System.out.println(new Date()); 33 Thread.sleep(1000000); 34 System.out.println("end!"); 35 os.close(); 36 is.close(); 37 socket.close(); 38 } catch (UnknownHostException e) { 39 // TODO Auto-generated catch block 40 System.out.println(new Date()); 41 e.printStackTrace(); 42 } catch (IOException e) { 43 // TODO Auto-generated catch block 44 System.out.println(new Date()); 45 e.printStackTrace(); 46 } 47 catch (InterruptedException e) { 48 // TODO Auto-generated catch block 49 System.out.println(new Date()); 50 e.printStackTrace(); 51 } 52 53 } 54 55 }
TCPServer.java
1 package socket; 2 3 import java.io.*; 4 import java.net.*; 5 6 public class TCPServer { 7 8 /** 9 * @param args 10 */ 11 public static void main(String[] args) { 12 // TODO Auto-generated method stub 13 try { 14 ServerSocket serverSocket = new ServerSocket(1287,2); 15 Socket socket = serverSocket.accept(); 16 17 PrintWriter os = new PrintWriter(socket.getOutputStream()); 18 BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream())); 19 while (true){ 20 System.out.println("Client: " + is.readLine()); 21 String msg = "hi"; 22 os.println(msg); 23 os.flush(); 24 System.out.println("Server: " + msg); 25 } 26 // os.close(); 27 // is.close(); 28 // socket.close(); 29 // serverSocket.close(); 30 } catch (IOException e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 } 34 // catch (InterruptedException e) { 35 // // TODO Auto-generated catch block 36 // e.printStackTrace(); 37 // } 38 39 } 40 41 }
UDPClient.java
1 package socket; 2 3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6 import java.net.InetAddress; 7 import java.net.SocketException; 8 import java.net.UnknownHostException; 9 10 public class UDPClient { 11 12 public static void main(String[] args) { 13 try { 14 DatagramSocket ds = new DatagramSocket(); 15 String str = "hello"; 16 DatagramPacket dp = new DatagramPacket(str.getBytes(),str.length(),InetAddress.getByName("22.11.143.60"),1287); 17 ds.send(dp); 18 19 ds.close(); 20 21 } catch (SocketException e) { 22 e.printStackTrace(); 23 } catch (UnknownHostException e) { 24 e.printStackTrace(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 29 } 30 31 }
UDPServer.java
1 package socket; 2 3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6 import java.net.SocketException; 7 8 public class UDPServer { 9 10 public static void main(String[] args) { 11 12 try { 13 DatagramSocket ds = new DatagramSocket(1287); 14 byte[] buf=new byte[100]; 15 DatagramPacket dp=new DatagramPacket(buf,100); 16 ds.receive(dp);// block here 17 System.out.println(new String(dp.getData())); 18 19 ds.close(); 20 21 } catch (SocketException e) { 22 e.printStackTrace(); 23 } catch (IOException e) { 24 e.printStackTrace(); 25 } 26 27 28 } 29 30 }