TCP/IP _ socket programming-Basic socket

Source: Internet
Author: User
Tags blab

Socket address
In Java, you can use the host name or host address to identify a network address, for example, www.baidu.com and 115.239.210.26, but the host name must be resolved to a digital address for Communication (DNS ), this process will take a certain amount of time, so we generally use a digital address in the program.
In Java, inetaddress represents a network destination address, including host name and number address information. It has two subclasses: inet4address and inet6address, which represent IPv4 and IPv6 addresses respectively, the following is a simple example program that prints all network interfaces and corresponding address information on a host and obtains the host address based on the host name, it may take a long time to locate a host using the host name.
public class InetAddressExample {        public static void main(String[] args) {              try {                    Enumeration<NetworkInterface> interfaceList = NetworkInterface                                 . getNetworkInterfaces();                     if (interfaceList == null) {                           System. out.println("No Interface Found" );                    } else {                            while (interfaceList.hasMoreElements()) {                                 NetworkInterface iface = interfaceList.nextElement();                                 System. out.println("Interface " + iface.getName());                                 Enumeration<InetAddress> addressList = iface                                               .getInetAddresses();                                  if(!addressList.hasMoreElements()){                                        System. out.println("No Address Found" );                                 }                                  while (addressList.hasMoreElements()) {                                        InetAddress address = addressList.nextElement();                                        System. out.println("address " +(address instanceof Inet4Address)+" ? v4" );                                        System. out.println("address " +(address instanceof Inet6Address)+" ? v6" );                                        System. out.println("host address  "+address.getHostAddress());;                                 }                                 System. out.println();                                  System. out.println("==========================" );                                 System. out.println();                           }                    }             } catch (SocketException e) {                    e.printStackTrace();             }                          String hosts[] = new String[]{"www.baidu.com" ,"blab.bl$ald" };                           for (String host : hosts) {                     try {                           InetAddress address[] = InetAddress.getAllByName(host);                            for (InetAddress inetAddress : address) {                                 System. out.println("host name:"+inetAddress.getHostName()+"  host address:" + inetAddress.getHostAddress());                           }                                               } catch (UnknownHostException e) {                           e.printStackTrace();                    }             }                    }}

Print Information

Interface loaddress true ? v4address false ? v6host address  127.0.0.1address false ? v4address true ? v6host address  0:0:0:0:0:0:0:1==========================Interface net0No Address Found==========================Interface net1No Address Found==========================Interface net2No Address Found==========================Interface ppp0No Address Found==========================Interface eth0No Address Found==========================Interface eth1No Address Found==========================Interface eth2No Address Found==========================Interface ppp1No Address Found==========================Interface net3No Address Found==========================Interface net4No Address Found==========================Interface eth3address false ? v4address true ? v6host address  fe80:0:0:0:8d48:2afb:e255:3d33%12==========================Interface net5No Address Found==========================Interface net6No Address Found==========================Interface eth4address false ? v4address true ? v6host address  fe80:0:0:0:2116:398c:e5a0:1392%15==========================Interface net7address true ? v4address false ? v6host address  192.168.12.104address false ? v4address true ? v6host address  fe80:0:0:0:5415:3c6f:45cb:8596%16==========================Interface net8No Address Found==========================Interface net9No Address Found==========================Interface net10address false ? v4address true ? v6host address  2001:0:4137:9e76:14bb:17de:c266:1e69address false ? v4address true ? v6host address  fe80:0:0:0:14bb:17de:c266:1e69%19==========================Interface net11No Address Found==========================Interface eth5No Address Found==========================Interface eth6address true ? v4address false ? v6host address  192.168.111.1address false ? v4address true ? v6host address  fe80:0:0:0:f9f0:272d:850c:9f63%22==========================Interface net12address false ? v4address true ? v6host address  fe80:0:0:0:0:5efe:c0a8:c68%23==========================Interface net13address false ? v4address true ? v6host address  fe80:0:0:0:0:5efe:c0a8:6f01%24==========================Interface net14No Address Found==========================Interface net15No Address Found==========================Interface eth7No Address Found==========================Interface eth8No Address Found==========================Interface net16No Address Found==========================Interface net17No Address Found==========================Interface eth9No Address Found==========================Interface eth10No Address Found==========================Interface eth11No Address Found==========================Interface net18No Address Found==========================Interface net19No Address Found==========================Interface net20No Address Found==========================host name:www.baidu.com  host address:115.239.210.26host name:www.baidu.com  host address:115.239.210.27java.net.UnknownHostException : blab.bl$ald       at java.net.Inet6AddressImpl.lookupAllHostAddr( Native Method)       at java.net.InetAddress$1.lookupAllHostAddr(Unknown Source)       at java.net.InetAddress.getAddressesFromNameService(Unknown Source)       at java.net.InetAddress.getAllByName0(Unknown Source)       at java.net.InetAddress.getAllByName(Unknown Source)       at java.net.InetAddress.getAllByName(Unknown Source)       at tu.bingbing.basesocket.InetAddressExample.main(InetAddressExample.java:50)

We can see that the loopback address (127.0.0.1) and the local address (192.168.12.104) finally took some time to parse the host name, but the host corresponding to it was not found, the inetaddress class can obtain information about the network address and some network address attributes. The networkinterface class can obtain some information about a host network interface, which is very helpful for programming.

TCP socket

The following is an example of testing the host feedback service program. The feedback service program simply sends the data packets sent to the server back to the client, some hosts may not return back to the service program. You can run Telnet "server.example.com 7" to check

public class TCPEchoClient {        /**        * @param args        */        public static void main(String[] args) throws Exception{                          String serverAddress = "127.0.0.1";              int serverPort = 7;                          Socket socket = new Socket(serverAddress,serverPort);                          InputStream in = socket.getInputStream();             OutputStream out = socket.getOutputStream();                           byte datas[] = "Hello World" .getBytes();                          out.write(datas);                           int totalBytesRecvd = 0;              int bytesRecvd = 0;                           while(totalBytesRecvd<datas.length ){                                                             if((bytesRecvd = in.read(datas, totalBytesRecvd, datas.length-totalBytesRecvd))==-1){                            throw new Exception("Server Closed Prematurelly");                    }                                        totalBytesRecvd += bytesRecvd;                                 }                          System. out.println("Received :" + new String(datas));                          socket.close();       }}

You may be wondering why you should write data like this when receiving the data returned by the feedback service program, directly in. read (datas, 0, datas. length) is not enough? This is because the TCP protocol cannot determine the boundary between the information sent in read () and write (). Although we only use one write () to send feedback strings. The feedback server may also accept information changes from multiple blocks. Even if the feedback string only exists in one block on the feedback server, it may be split into multiple blocks when returned. But do you have any questions about how to do that in our program? If the sending order of the feedback information block is disrupted, will we not be able to receive the correct information? You don't have to worry about it, don't forget that the TCP protocol can repair and detect possible packet loss, duplication, order disruption, and other errors between hosts and the channels between hosts provided by the IP layer.

The work of the server is to establish a communication terminal and passively wait for the client connection. When creating a serversocket instance, You need to specify the port number to listen to, but you do not need to specify a host address, because a host may have many network interface addresses, we do not specify which interface address can communicate with other hosts. Otherwise, it will automatically select an 'available' address for communication. When serversocket calls the accept () method, It will be blocked, when a client connects, it will obtain a socket instance that has established a connection with the client, so that it can communicate with the client. The following is an example of a TCP server.

Public class tcpechoserverexample {/*** @ Param ARGs */public static void main (string [] ARGs) throws exception {int bufsize = 32; int listenerport = 9999; serversocket = new serversocket (listenerport); int bytes emsgsize = 0; byte [] receivebuf = new byte [bufsize]; while (true) {Socket socket = serversocket. accept (); // obtain the client host address socketaddress cltaddress = socket. getremotesocketaddh SS (); system. out. println ("client address:" + cltaddress); inputstream cltin = socket. getinputstream (); outputstream cltout = socket. getoutputstream (); While (optional emsgsize = cltin. read (receivebuf ))! =-1) {cltout. Write (receivebuf, 0, receivemsgsize);} socket. Close ();}}}

If one end of the TCP connection is always writing data to the output stream, and the input stream associated with the other end of the connection does not call the read () method, the write () method may be blocked, if you do not proceed, some unpredictable consequences will occur, and you will learn the countermeasures to cope with this situation later.

UDP socket

The UDP protocol provides an end-to-end service different from the TCP protocol. The UDP protocol mainly performs two tasks: adding another layer of IP address (port) based on the IP protocol ); this module detects possible errors during data transmission and discards damaged data. UDP sockets do not need to be connected before use. The UDP protocol is the same as sending emails. You only need to specify your 'mail address ', each sent message contains the destination address information, which is independent from other information. Once a UDP socket is created, it can send information to any address, or accept information from any address. UDP will save the boundary information, so that when the application receives information, in some ways, it is simpler than TCP. UDP may cause data loss and disordered data order during the transmission of data packets. Therefore, we need to process these situations when using the UDP protocol. To put it simply, when UDP sends data, no matter whether the data reaches the destination or not, the transmission speed is faster. However, data may also be lost. TCP, we know that three handshakes are established and four handshakes are released, so the transmission is more accurate, but the speed may be relatively slow.
In Java, UDP sockets are used by using mongoramsocket and mongorampacket. Unlike TCP sockets that use byte streams to transmit information, UDP sockets use a self-contained information called data packets, which is represented by datagrampacket, datagrampacket contains the destination address and port number to be delivered. On the contrary, it also contains the source destination address and port number. Use the datagramsocket. Send () method to send the datagrampacket packet, which is received by datagramsocket. Receive. Below is a simple UDP client example
     public class UDPEchoClientTimeoutExample {        public static void main(String[] args) throws Exception{             InetAddress serverAddress = InetAddress.getByName("www.baidu.com");             System. out.println(serverAddress.getCanonicalHostName());              int serverPort = 80;                          DatagramSocket dSocket = new DatagramSocket();             dSocket.setSoTimeout(3000);                           byte[] sendMsgBuf = "Hello World" .getBytes();             DatagramPacket sendDp = new DatagramPacket(sendMsgBuf, sendMsgBuf.length, serverAddress, serverPort);             DatagramPacket receiveDp = new DatagramPacket(new byte[sendMsgBuf.length ], sendMsgBuf.length);              int tries = 0;              boolean receiveResp = false;              do {                                        dSocket.send(sendDp);                                         try{                           dSocket.receive(receiveDp);                            if(!receiveDp.getAddress().equals(serverAddress)){                                  throw new Exception("receive an unknow address");                           }                           receiveResp = true;                    } catch(Exception e){                           tries++;                                               }                                                     } while ((!receiveResp)&&(tries<3));                           if(receiveResp){                    System. out.println("received data:" +new String(receiveDp.getData() ));             } else{                    System. out.println("no data received" );             }                          dSocket.close();       }}

It should be noted that the receive () method of mongoramsocket may not receive the data packets returned by the server. If the receiving timeout time is not specified, it will be blocked all the time. This is obviously not what we want, the above example shows that, if 3 S does not receive Ive, it will be tried three times in a row. mongoramsocket can also be set to connect (inetaddress address, int port) with the specified destination address ), when a connection is set to a specified destination address, mongoramsocket cannot send or receive data packets from other destination addresses than the specified destination address, however, it should be noted that UDP does not establish end-to-end connections. connectconnect (inetaddress address, int port) only establishes local operations, and disconnect () can be used () to clear the remote destination address and port number UDP feedback server socket is also passively waiting for the client UDP client socket connection, UDP is not connected, the server and the client does not establish a connection, you can only specify the destination address and port number of the client data packets to communicate with the server. The following is a simple example.

     public class UDPEchoServerExample {    /**     * @param args     * @throws IOException     */    public static void main(String[] args) throws IOException {        int serverPort = 9997;        int maxBufferSize = 255;               DatagramSocket serverDs = new DatagramSocket(serverPort);               DatagramPacket dp = new DatagramPacket( new byte[maxBufferSize], maxBufferSize);               while (true ){            serverDs.receive(dp);            System. out .println("client address : " + dp.getSocketAddress()+ "    receive data : "+ new String(dp.getData()));            serverDs.send(dp);            dp.setLength(maxBufferSize); // reset the packet buffer size        }           }     }

The buffer size of the server-side data packets is reset every time the receive sends data packets to the client. The number of bytes may be reduced. The information may be truncated the next time you receive the client datagram, therefore, you need to reset DP every time. setlength (maxbuffersize) We also need to note that when the client UDP socket needs to send data packets, it sets the internal offset and length of the cache zone to senddp. setdata (sendmsgbuf,
6, 2) if the server UDP socket uses DP. if getdata () is used to obtain the expected result, it should be obtained according to the internal offset and length of the cache area set by the client socket, because the data cache area received by the server socket only changes the internal offset and length set by the client to determine the region, we can obtainByte[]
Destbuf = arrays.Copyofrange(DP. getdata (),
DP. getoffset (), DP. getoffset () + dp. getlength () corresponds to the client settings.
Another point is to look at our UDP server program. When constructing mongorampacket, we specify that the data received from the client is stored in a cache zone, however, we do not know how big the cache zone should be. If it is set to a small value, the data will be truncated and no prompt will be given to us, the UDP Protocol specifies that the maximum number of bytes for each data packet is 65507. Therefore, it is better for the server to use a cache area of about 65600 bytes.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.