"JAVA" Socket programming

Source: Internet
Author: User

For Java socket programming, there are two concepts, one is serversocket and the other is a socket. A connection is established between the server and the client through the socket, and then they can communicate. First ServerSocket will listen to a port on the server, when it discovers that the client has a socket to try to connect it, it will accept the connection request of the socket, and establish a corresponding socket on the server to communicate with it. So there are two sockets, the client and the server.

For the communication between the sockets is very simple, the server to the socket output stream to write something, the client can be through the socket input stream to read the corresponding content. Socket and socket are two-way connectivity, so the client can also write to the corresponding socket output stream, and then the service side of the corresponding socket input stream can read the corresponding content.

public Class Server {public static void main (string[] args) {try {serversocket Server = new ServerSocket (9900);      A blocking method that attempts to receive a connection call native method receives the request socket socket = server.accept ();   Receive data reader reader = new InputStreamReader (Socket.getinputstream ());   char[] Clientstr = new char[64];   int length = Reader.read (CLIENTSTR);      System.out.println (New String (clientstr, 0, length));   Send data writer writer = new OutputStreamWriter (Socket.getoutputstream ());   Writer.write ("Return param");   Writer.flush ();//note Refresh the stream buffer, avoid two-way wait writer.close ();   Reader.close ();   Socket.close ();   Server.close ();  } catch (IOException e) {//TODO auto-generated catch block E.printstacktrace (); }  }}
When the Server.accept () method executes, suspends waiting for the receive connection and gets the socket, where the Socketaccept method called in accept is the native method, and the connection information is obtained through the kernel public class Client {public static void main (string[] args) {try {socket Client = new socket ("127.0.0.1", 9900);   Writer writer = new OutputStreamWriter (Client.getoutputstream ());   Writer.write ("Request param");   Writer.flush ();//Refreshes the buffer of the stream//Gets the returned results reader reader = new InputStreamReader (Client.getinputstream ());   char[] Clientstr = new char[64];   int length = Reader.read (CLIENTSTR);   System.out.println (New String (clientstr, 0, length));   Writer.close ();   Reader.close ();  Client.close ();  } catch (IOException e) {e.printstacktrace (); }}} here to flush, only so that the server can receive the data sent by the client, or may cause the two sides infinite waiting for each other Multiple clients connect to the same server

As mentioned in the previous two examples are the server to receive a client's request after the end, can no longer receive requests from other clients, which is often not enough to meet our requirements. Usually we do this:

public class Server {public static void main (String args[]) throws IOException {//For the sake of simplicity, all exception information is thrown out int por      t = 8899;      Define a ServerSocket listener on port 8899 serversocket server = new ServerSocket (port);         while (true) {//server attempts to receive connection requests from other sockets, the server's accept method is a blocked socket socket = server.accept ();       After establishing a connection with the client, we can get the inputstream of the socket and read the message from the client.         Reader reader = new InputStreamReader (Socket.getinputstream ());         Char chars[] = new CHAR[64];         int Len;         StringBuilder sb = new StringBuilder ();         String temp;         int index;            while ((Len=reader.read (chars))! =-1) {temp = new String (chars, 0, Len);                if (index = Temp.indexof ("EOF"))! =-1) {//when encountering EOF, end receiving Sb.append (temp.substring (0, index));            Break         } sb.append (temp);         } System.out.println ("From client:" + SB); After reading, write a writer writer = new OUTPUTSTREAMWRITER (Socket.getoutputstream ());         Writer.write ("Hello Client.");         Writer.flush ();         Writer.close ();         Reader.close ();      Socket.close (); }   }   }

In the above code we used a dead loop in which ServerSocket calls its accept method to attempt to receive a connection request from the client. When the request is not received, the program blocks until it receives a connection request from the client, then communicates with the client that is currently establishing the connection, and then executes the loop body to try to receive the new connection request again. This way our ServerSocket can receive connection requests from all clients and communicate with them. This enables a simple mode of communication between a server and multiple clients.

Although the above example implements a server to communicate with multiple clients, there is a problem. In the above example, our server processing client's connection request is synchronous, each time after receiving a connection request from the client, we must first communicate with the current client before processing the next connection request. This can seriously affect the performance of the program in the case of more concurrency, so we could change it to the way that asynchronous processing communicates with the client:

public class Server {public static void main (String args[]) throws IOException {//For the sake of simplicity, all exception information is thrown out int p      ORT = 8899;      Define a ServerSocket listener on port 8899 serversocket server = new ServerSocket (port);         while (true) {//server attempts to receive connection requests from other sockets, the server's accept method is a blocked socket socket = server.accept ();      A new thread is created for each socket that is received to process it. Start ();            }}/** * * * Static class Task implements Runnable {Private socket socket for processing Socket request;      Public Task (socket socket) {this.socket = socket;         } public void Run () {try {handlesocket ();         } catch (Exception e) {e.printstacktrace (); }}/** * communicates with the client socket * @throws Exception */private void Handlesocket () throws         Exception {Reader reader = new InputStreamReader (Socket.getinputstream ());      Char chars[] = new CHAR[64];   int Len;         StringBuilder sb = new StringBuilder ();         String temp;         int index;            while ((Len=reader.read (chars))! =-1) {temp = new String (chars, 0, Len);                if (index = Temp.indexof ("EOF"))! =-1) {//when encountering EOF, end receiving Sb.append (temp.substring (0, index));            Break         } sb.append (temp);         } System.out.println ("From client:" + SB);         After reading, write a writer writer = new OutputStreamWriter (Socket.getoutputstream ());         Writer.write ("Hello Client.");         Writer.flush ();         Writer.close ();         Reader.close ();      Socket.close (); }         }   }

In the above code, each time ServerSocket receives a new socket connection request, it will start a new thread to communicate with the current socket, thus achieving asynchronous processing to communicate with the client socket.

When it comes to receiving data from the socket's inputstream, a little bit of reading like the one above is too complicated, and sometimes we switch to using BufferedReader to read a line at a time, such as:

public class Server {public static void main (String args[]) throws IOException {//For the sake of simplicity, all exception information is thrown out int por      t = 8899;      Define a ServerSocket listener on port 8899 serversocket server = new ServerSocket (port);         while (true) {//server attempts to receive connection requests from other sockets, the server's accept method is a blocked socket socket = server.accept ();      A new thread is created for each socket that is received to process it. Start ();            }}/** * * * Static class Task implements Runnable {Private socket socket for processing Socket request;      Public Task (socket socket) {this.socket = socket;         } public void Run () {try {handlesocket ();         } catch (Exception e) {e.printstacktrace (); }}/** * communicates with the client socket * @throws Exception */private void Handlesocket () throws E         xception {BufferedReader br = new BufferedReader (New InputStreamReader (Socket.getinputstream ())); StringBuilder SB = new StringBuilder ();         String temp;         int index;            while ((Temp=br.readline ()) = null) {System.out.println (temp);                if (index = Temp.indexof ("EOF"))! =-1) {//when encountering EOF, end receiving Sb.append (temp.substring (0, index));            Break         } sb.append (temp);         } System.out.println ("From client:" + SB);         After reading, write a writer writer = new OutputStreamWriter (Socket.getoutputstream ());         Writer.write ("Hello Client.");         Writer.write ("eof\n");         Writer.flush ();         Writer.close ();         Br.close ();      Socket.close (); }   }}

It is important to note that BufferedReader's ReadLine method is a one-time read line, and this method is blocked until it reads a line of data so that the program will continue to execute, so when will readline read a line? Until the program encounters a newline character or the Terminator ReadLine method of the corresponding stream, it will think that it has read a line before it ends its blocking and the program continues to execute. So when we use the BufferedReader readline to read the data, we must remember that in the corresponding output stream must write a newline character (after the end of the stream is automatically marked as the end, ReadLine can be recognized), After writing a newline character, remember to flush the output stream if it is not closed immediately, so that the data is actually written from the buffer. Corresponding to the above code, our client program should write this:
public class Client {public   static void Main (String args[]) throws Exception {      //For the sake of simplicity, all exceptions are thrown directly out of     String H ost = "127.0.0.1";  The server-side IP address to connect     int port = 8899;   The listener port corresponding to the server to be connected     //Connect with the server     socket client = new socket (host, port);      After the connection is established, the data can be written to the server.     writer writer = new OutputStreamWriter (Client.getoutputstream ());      Writer.write ("Hello Server.");      Writer.write ("eof\n");      Writer.flush ();      After writing, read operations     bufferedreader br = new BufferedReader (New InputStreamReader (Client.getinputstream ()));      StringBuffer sb = new StringBuffer ();      String temp;      int index;      while ((Temp=br.readline ()) = null) {         if (index = Temp.indexof ("EOF"))! =-1) {            sb.append (temp.substring (0, I Ndex));            break;         }         Sb.append (temp);      }      SYSTEM.OUT.PRINTLN ("From server:" + SB);      Writer.close ();      Br.close ();      Client.close ();   }}

4. Set timeout period

Assuming that there is a requirement, our client needs to obtain the XX information from the server through the socket and then present it to the user on the page. We know that the socket is blocked when reading the data, and if it is not read, the program will always block there. We must not allow this to happen when synchronizing requests, which requires us to control blocking interrupts after the request has reached a certain time, allowing the program to continue running. The socket provides us with a setsotimeout () method to set the time-out for receiving data in milliseconds. When the timeout period is greater than 0, and the socket has not received the returned data, the socket will throw a sockettimeoutexception.

Let's say we need to control how our clients interrupt blocking if they haven't read the data for 10 seconds before they start reading the data, we can do this:

public class Client {public static void main (String args[]) throws Exception {//For the sake of simplicity, all exceptions are thrown directly out of String Ho  st = "127.0.0.1";   The server-side IP address to connect int port = 8899;      The listener port corresponding to the server to be connected//connect with the server socket client = new socket (host, port);      After the connection is established, the data can be written to the server. Writer writer = new OutputStreamWriter (Client.getoutputstream ());      Writer.write ("Hello Server.");      Writer.write ("eof\n");      Writer.flush ();      After writing, read operations BufferedReader br = new BufferedReader (New InputStreamReader (Client.getinputstream ()));      Set the timeout time to 10 seconds client.setsotimeout (10*1000);      StringBuffer sb = new StringBuffer ();      String temp;      int index;                try {while ((Temp=br.readline ()) = null) {if (index = Temp.indexof ("EOF"))! =-1) {                Sb.append (temp.substring (0, index));            Break         } sb.append (temp); }} catch (Sockettimeoutexception e) {System.out.println ("data read timeout.      ");      }SYSTEM.OUT.PRINTLN ("From server:" + SB);      Writer.close ();      Br.close ();   Client.close ();  }}
5, receive data garbled

In this case, the server or the client receives Chinese garbled characters usually because the encoding used when the data is sent is inconsistent with the encoding used when it is received. For example, the following section of the service-side code:

public class Server {public static void main (String args[]) throws IOException {//For the sake of simplicity, all exception information is thrown out int PO      RT = 8899;      Define a ServerSocket listener on port 8899 serversocket server = new ServerSocket (port);         while (true) {//server attempts to receive connection requests from other sockets, the server's accept method is a blocked socket socket = server.accept ();      A new thread is created for each socket that is received to process it. Start ();            }}/** * * * Static class Task implements Runnable {Private socket socket for processing Socket request;      Public Task (socket socket) {this.socket = socket;         } public void Run () {try {handlesocket ();         } catch (Exception e) {e.printstacktrace (); }}/** * communicates with the client socket * @throws Exception */private void Handlesocket () throws E         xception {BufferedReader br = new BufferedReader (New InputStreamReader (Socket.getinputstream (), "GBK")); StrIngbuilder sb = new StringBuilder ();         String temp;         int index;            while ((Temp=br.readline ()) = null) {System.out.println (temp);                if (index = Temp.indexof ("EOF"))! =-1) {//when encountering EOF, end receiving Sb.append (temp.substring (0, index));            Break         } sb.append (temp);         } System.out.println ("Client:" + SB);         After reading, write a writer writer = new OutputStreamWriter (Socket.getoutputstream (), "UTF-8"); Writer.write ("Hello, client.")         ");         Writer.write ("eof\n");         Writer.flush ();         Writer.close ();         Br.close ();      Socket.close (); }   }}

       

It's a bit confusing for me to test here. In the service-side code above, we explicitly define the input stream by using GBK encoding to read the data, and when defining the output stream it is explicitly specified that the data will be sent using UTF-8 encoding. If the client sends the data at the time not to send the GBK encoding, the data received by the server is likely to be garbled, also if the client receives the data when the server does not send data encoding, that is, UTF-8 encoding to receive data, it is also very likely to appear garbled data. Therefore, for the above service-side code, in order to enable our program to read the data sent by the other side, without garbled situation, our client should be this: public class client {    public static void Main (String args[]) throws Exception {     //For simplicity, all exceptions are directly thrown out      string host = "127.0.0. 1 ";  //IP address of the server to be connected      int port = 8899;  //The listener port for the server to be connected      //connection to the server      socket client = new Socket (host, port);  &N Bsp  //Set up a connection to write data to the server      writer Writer = new OutputStreamWriter (Client.getoutputstream (), "GBK"); nbsp     Writer.write ("Hello, service side." ");      Writer.write (" eof\n ");      Writer.flush ();     //Read after finish      bufferedreader br = new BufferedReader (New InputStreamReader (Client.getinputstream (), "UTF-8")); NBsP    //Set timeout to 10 seconds      client.setsotimeout (10*1000);      StringBuffer sb = new Stri Ngbuffer ();      String temp;      int index;      try {         while ((Temp=br.readline ()) = null) {            if ((index = Temp.indexof ("EO F ")) =-1) {                Sb.append (temp.substring (0, index));    &NB Sp           break;           }          &NB Sp Sb.append (temp);         }     } catch (Sockettimeoutexception e) {         SYSTEM.OUT.PRINTLN ("Data read timeout. ");     }      SYSTEM.OUT.PRINTLN (" server: "+ SB);      Writer.close ();      Br.close ();      client.close ();   }

"JAVA" Socket programming

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.