Use TCP to transmit data, write the program of client and server, and realize the real-time communication between the two programs.
In each program, the function of sending and receiving data in real time is realized.
The program takes the close string input at both ends as the end identifier. When one end inputs close, the transmission is terminated, and when one end receives close, the reception is terminated. The demonstrated client comes from the personal computer IDEA debugging run. The server side comes from the jdk environment under the centos system of Alibaba cloud server. The program needs to use the knowledge of java I/O flow, multithreading and network programming.
1, Client
Since sending and receiving data are parallel, in order to enable the function of receiving and sending at the same time at any time, multi threading is used to encapsulate the receiving and sending into two Runnable implementation classes respectively. Get io information.
Source code of ClientDemo class:
public class ClientDemo { public static Socket s; public static void main(String[] args) throws IOException, InterruptedException { s = new Socket("localhost", 10000); //Enter the server ip address in parameter 1 here System.out.println("Connection successful"); Thread send = new Thread(new COUT()); Thread receive = new Thread(new CIN()); send.start(); receive.start(); send.join(); //When sending and receiving are completed, close the socket receive.join(); //Therefore, when the two threads end, they return to the main thread for execution. s.close(); } }
Create a global variable socket s, initialize s in the main process, and then start the two threads of sending and receiving functions.
Two parameters passed during Socket construction, one of which is to fill in the server address. Or fill in localhost, i.e. 127.0.0.1 loopback address, and the machine can run the server and client for local data transmission.
The second is the number of ports. It is necessary to keep the number of ports bound by sockets on the client and server consistent. Select as many ports as possible to avoid being occupied. If the operation reports that the port is occupied, you can try to change the number of ports within 65536.
Source code of client sending and receiving classes:
class CIN implements Runnable{ @Override public void run() { //Receiving module try { InputStream is = ClientDemo.s.getInputStream();//Get the connected stream through the global socket s in(is); } catch (IOException o) { o.printStackTrace(); } } public static void in(InputStream is) throws IOException{ while(true){ byte[] bytes = new byte[1024]; int len = is.read(bytes); String line = new String(bytes,0,len); System.out.println("other party: "+line); if(line.equals("close")) break; } } } class COUT implements Runnable{ @Override public void run() { //Sending module try { OutputStream os = ClientDemo.s.getOutputStream();//Socket fetch stream out(os); } catch (IOException o){ o.printStackTrace(); } } public static void out(OutputStream os) throws IOException{ Scanner sc = new Scanner(System.in); while(true) { String line = sc.nextLine(); os.write(line.getBytes()); if(line.equals("close")) break; } sc.close(); } }
Since all IO streams are created by socket s, you need to close s at the end of the program.
2, Server
Source code of ServerDemo class:
public class ServerDemo { public static ServerSocket ss; public static Socket s; public static void main(String[] args) throws IOException, InterruptedException { ss = new ServerSocket(10000); //Listening port 10000, corresponding to the port bound by the client socket s = ss.accept(); //Extract a connection from the listening socket System.out.println("Connection successful"); Thread send = new Thread(new SOUT()); Thread receive = new Thread(new SIN()); send.start(); receive.start(); send.join(); receive.join(); ss.close(); } }
Create a server socket object, listen, and receive connection requests.
The code here is similar to that of the client. The code after connection is basically the same.
Source code of server-side sending and receiving classes:
class SIN implements Runnable{ @Override public void run() { try { InputStream is = ServerDemo.s.getInputStream(); in(is); } catch (IOException o) { o.printStackTrace(); } } public static void in(InputStream is) throws IOException{ while(true){ byte[] bytes = new byte[1024]; int len = is.read(bytes); String line = new String(bytes,0,len); System.out.println("other party: "+line); if(line.equals("close")) break; } } } class SOUT implements Runnable{ @Override public void run() { try { OutputStream os = ServerDemo.s.getOutputStream(); out(os); } catch (IOException o){ o.printStackTrace(); } } public static void out(OutputStream os) throws IOException{ Scanner sc = new Scanner(System.in); while(true) { String line = sc.nextLine(); os.write(line.getBytes()); if(line.equals("close")) break; } sc.close(); } }
The difference between the two codes is that due to different sockets, the returned stream instances are different. The basic logic is the same.
The client and server can be run locally at the same time. The client socket is bound with the local ip address, "localhost" or 127.0.0.1.
First turn on the server to listen, and then turn on the client to send a connection request to the server. After successful connection, you can chat in real time. In the program, a behavior information unit is used to type several characters and send them on a new line. The other end can receive the message.
Type "close" send at one end to close the sending thread of the current program and the receiving thread of the receiving program. When all sending and receiving of the two programs are finished, close the program.
Actual measurement record: send the server-side program to ECs, run it through jdk, start program listening, and point the socket of the client to the address and listening port of the server-side. After that, the connection is established, and the information can be transmitted freely at both ends.