1. Introduction to TCP/IP
The TCP/IP protocol family is a protocol used by the Internet and can also be used in independent private networks.
The TCP/IP protocol family includes IP protocol, TCP protocol and UDP protocol.
The IP protocol uses IP addresses to distribute packets, but it is a best-effort service, and packets may be lost, out of order, or repeated. The TCP and UDP protocols add port numbers to the IP protocol, thereby establishing a transparent connection between the applications of the two hosts.
The difference is that the TCP protocol fixes IP layer errors, which establishes connections between hosts through handshake messages.
Then, the errors in the message are restored by adding a serial number to the message. UDP simply extends the IP protocol.
Enable it to work between applications, not between hosts.
Regarding IP addresses, a host can have multiple network interfaces, and one interface can have multiple addresses.
Some IP addresses have special uses:
A. Loopback address: 127.0.0.1, is always assigned to a loopback interface, mainly used for testing.
B. Private address: Starting with 10, 192.168, 172.(16-31), used for private networks. When a NAT device forwards a message, it maps the private address port pair of the message in one interface into the public address port pair in another interface. This enables a small group of hosts to share an IP address pair.
C. Multicast address: The first number is between 224 and 239.
2. Socket Basics
1. Obtaining address
public static void main(String[] args) { try { Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface iface = interfaces.nextElement(); System.out.println("Interface: " + iface.getName()); Enumeration<InetAddress> addrList = iface.getInetAddresses(); if (!addrList.hasMoreElements()) System.out.println("No address"); while (addrList.hasMoreElements()) { InetAddress address = addrList.nextElement(); System.out.println("Address: " + address.getHostAddress()); } } } catch (SocketException e) { e.printStackTrace(); } }2.TCP instance program
It should be noted that although only one write() method is used to send strings on the Client side, the server side may also receive this information from multiple blocks. Even if the feedback string is stored in a block when the server returns, it may be TCP
The protocol is divided into multiple parts.
TCPEchoClientTest.java
public static void main(String[] args) throws IOException { String server = args[0]; byte[] data = args[1].getBytes(); int port = 7; Socket socket = new Socket(server, port); System.out.println("Connected to server..."); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); out.write(data); int totalBytesRcvd = 0; int bytesRcvd; while (totalBytesRcvd < data.length) { if ((bytesRcvd = in.read(data, totalBytesRcvd, data.length - totalBytesRcvd)) == -1) throw new SocketException("Connection closed"); totalBytesRcvd += bytesRcvd; } System.out.println("Received: " + new String(data)); socket.close(); }TCPEchoServerTest.java
private static final int BUFSIZE = 32; public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(7); int recvMsgSize; byte[] receiveBuf = new byte[BUFSIZE]; while (true) { Socket socket = serverSocket.accept(); System.out.println("Handling client " + " from remote " + socket.getRemoteSocketAddress() + " at local " + socket.getLocalSocketAddress()); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); while ((recvMsgSize = in.read(receiveBuf)) != -1) { out.write(receiveBuf, 0, recvMsgSize); } socket.close(); } }Note that the new Socket specifies the port number that the remote server listens to without specifying the local port, so the default address and available port number will be used. On my machine Client port is 4593, connected to port 7 of the server.
3. UDP instance program
Why use UDP protocol? If the application only exchanges a small amount of data, the establishment phase of the TCP connection will transmit at least twice its information (and twice the round trip time).
UDPEchoClientTest.java
public static void main(String[] args) throws IOException { InetAddress serverAddress = InetAddress.getByName(args[0]); byte[] bytesToSend = args[1].getBytes(); DatagramSocket socket = new DatagramSocket(); socket.setSoTimeout(3000); DatagramPacket sendPacket = new DatagramPacket( bytesToSend, bytesToSend.length, serverAddress, 7); DatagramPacket receivePacket = new DatagramPacket( new byte[bytesToSend.length], bytesToSend.length); // Packets may be lost, so we have to keep trying int tries = 0; boolean receivedResponse = false; do { socket.send(sendPacket); try { socket.receive(receivePacket); if (!receivePacket.getAddress().equals(serverAddress)) throw new IOException("Receive from unknown source"); receivedResponse = true; } catch (IOException e) { tries++; System.out.println("Timeout, try again"); } } while (!receivedResponse && tries < 5); if (receivedResponse) System.out.println("Received: " + new String(receivePacket.getData())); else System.out.println("No response"); socket.close(); } UDPEchoServerTest.java
private static final int ECHOMAX = 255; public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(7); DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX); while (true) { socket.receive(packet); System.out.println("Handling client at " + packet.getAddress()); socket.send(packet); packet.setLength(ECHOMAX); } }Comparing this example with the previous TCP instance, there are the following differences:
A.DatagramSocket does not need to specify the destination address when it is created, because UDP does not need to establish a connection, and each data packet can be sent or received from a different destination address.
B. If you block and wait on read() like TCP, it may be blocked there forever, because the UDP protocol simply extends the IP protocol, and UDP packets may be lost. Therefore, you must set the timeout time for blocking waiting.
C.UDP protocol retains the boundary information of the message, and each receive() call can only receive the data sent by the send() method call once.
D. The maximum data that a UDP packet can transmit is 65507 bytes. The excess bytes will be automatically discarded, and there is no prompt for the receiving program. Therefore, it is safe to set the cache array to about 65,000 bytes.
E. If the receive() method is repeatedly called with the same DatagramPacket instance, the internal length of the message must be explicitly reset to the actual length of the cache before each call.