Network programming self-made communication gadget (with source code)

catalogue

I. Introduction

Second, write source code

2.1 create server and client

2.3 create function

Three renderings

IV. summary

V. source code

I. Introduction

Readers can understand the code and self-made by mastering the basic knowledge of multithreading, io flow and network programming. It is very easy to understand and learn. Those who do not understand individual code can also find information on the Internet. The source code will be attached later. I hope you can gain something

Second, write source code

2.1 create server and client

There must be at least two servers for communication. Here, in order to facilitate testing, two projects are established, and then exported for observation. Readers can directly establish two packages, which can be implemented as well, and even add or modify some functions on my basis

public class MyServer  {
	//Server
	public static void main(String[] args) throws Exception {//Throw exception
		//Create listening port
		ServerSocket ss=new ServerSocket(8998);//The port must be consistent and cannot be duplicate with the existing port of the computer
		//Call the accept method of the listening port object to receive the connection request from the client
		Socket socket;//The following should receive an accept method to receive client information. I put it below
public class MyClient  {
//client
	public static void main(String[] args) throws Exception {
		//Create a socket object and request to connect to the remote server
		Socket socket=new Socket("localhost",8998);//Native and port
		

TCP triple handshake process

1. Host A sends A data segment containing the flag bit of the synchronization serial number to host B and requests host B to establish A connection. Through this data segment, host A tells host B two things: I want to communicate with you; Which serial number can you use as the starting data segment to respond to me

//Send message to client
		boolean flag=true;
		Scanner input=new Scanner(System.in);
		while(true) {
			while(flag) {
				System.out.println("Protocol: group chat prefix“ all:"Private chat "person name:", login“ login: "");
				flag=false;
				
			}
			System.out.println("Please enter a message:");
			String message=input.next();
			byte[] buffer=message.getBytes();
			
			//Use the output stream to send messages to the server
			OutputStream os=socket.getOutputStream();
			
			os.write(buffer);

2 after receiving the request from host A, host B responds to host A with A data segment with acknowledgement (ACK) and synchronization serial number (SYN) flag bits, and also tells host A two things: I have received your request, and you can transmit data; Which serial number do you want to use as the starting data segment to respond to me

while(true){
			
			System.out.println("Ready to receive client connections");
			 socket=ss.accept();//Responsible for communicating with connected customers
			System.out.println("A client is connected:"+socket.getRemoteSocketAddress());
			
			//Create a thread that can receive port requests and messages at the same time
			ServerRecive sr=new ServerRecive(socket);
			sr.start();
			
			
			
		}

3 after receiving this data segment, host A sends A confirmation response to confirm that it has received the data segment of host B: "I have received the reply, and I will start transmitting the actual data now. In this way, the three handshakes are completed, and host A and host B can transmit data

//Create a thread to receive server replies
		ClientReceiver cr=new ClientReceiver(socket);
		cr.start();

I only use one thread here. You can also consider using two threads

2.3 create function

Chat is generally divided into group chat and private chat, so we should have these two functions, but how to distinguish group chat and private chat? QQ is distinguished by @ all members and @ personal nicknames. We can also make a similar agreement and make a function to distinguish them,

Here is a login function without password

while(true) {
							
						
						//Judge whether the current user is logged in
						String address=socket.getRemoteSocketAddress().toString();
						InputStream is = socket.getInputStream();
						byte[] buffer=new byte[1024];
						int r=is.read(buffer);
						String mess=new String(buffer,0,r);
						 int i=0;
						if(mess.startsWith("login:")) {
							
							UserManager.login(address, new Customer(mess.split(":")[1], socket));
							OutputStream os=socket.getOutputStream();
							
								byte[] reply="Login succeeded".getBytes();
								os.write(reply);



else {
								
								OutputStream os=socket.getOutputStream();
								byte[] reply="Please log in first".getBytes();
								os.write(reply);
							
								
							}}




//Log login information into the map collection
	public static void login(String address, Customer customer) {
		users.put(address, customer);
	}

Then there is the distinction between group chat and private chat

if(UserManager.checkLogin(address)) {
								
								String[] s=mess.split(":");//mess stores the information transmitted by the client
								//by the advices
								//Judge group chat or private hair
								if(s[0].equals( "all")) {//This means that the prefix is all:
									Collection<Customer> users=UserManager.getAllCustomer();//Get everyone's information, create a class, which stores the user name and address
									System.out.println("Now there are"+users.size()+"People online");
									
									for (Customer customer : users) {//Traverse and pass on what you say to everyone
										if(!(customer.getUsername().equals(UserManager.getUsername(address).getUsername()))) {
										
											OutputStream os=customer.getSocket().getOutputStream();
											byte[] messages=(UserManager.getUsername(address).getUsername()+
													"say:"+s[1]).getBytes();
											os.write(messages);
										}//Ignore yourself
												
												
									}
								}else {
									//Obtain the socket corresponding to the user from the map set according to the user name to which the message is to be forwarded
									Socket target=UserManager.getSocketByUsername(s[0]);
									OutputStream os=target.getOutputStream();
									byte[] messages=(UserManager.getUsername(address).getUsername()+
											"To you:"+s[1]).getBytes();
									os.write(messages);
											
								}

Three renderings

 

IV. summary

It's easy. It's done all at once. The code is a process of continuous writing. I hope readers can write it several times to deepen their understanding. copy alone is useless. There are too many details to pay attention to. An carelessness is a series of bug s. For example, English symbols should be used in the middle of the test

V. source code

package qqserver;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class ServerRecive extends Thread {
	//Server processing thread
	
		private Socket socket;

		public ServerRecive(Socket socket) {
			super();
			this.socket = socket;
		}
		@Override
		public void run() {
			//Receive messages from clients
			
					
					try {
						while(true) {
							
						
						//Judge whether the current user is logged in
						String address=socket.getRemoteSocketAddress().toString();
						InputStream is = socket.getInputStream();
						byte[] buffer=new byte[1024];
						int r=is.read(buffer);
						String mess=new String(buffer,0,r);
						 int i=0;
						if(mess.startsWith("login:")) {
							
							UserManager.login(address, new Customer(mess.split(":")[1], socket));
							OutputStream os=socket.getOutputStream();
							
								byte[] reply="Login succeeded".getBytes();
								os.write(reply);
							
							
						}else {
							
							if(UserManager.checkLogin(address)) {
								
								String[] s=mess.split(":");
								//by the advices
								//Judge group chat or private hair
								if(s[0].equals( "all")) {
									Collection<Customer> users=UserManager.getAllCustomer();
									System.out.println("Now there are"+users.size()+"People online");
									
									for (Customer customer : users) {
										if(!(customer.getUsername().equals(UserManager.getUsername(address).getUsername()))) {
										
											OutputStream os=customer.getSocket().getOutputStream();
											byte[] messages=(UserManager.getUsername(address).getUsername()+
													"say:"+s[1]).getBytes();
											os.write(messages);
										}
												
												
									}
								}else {
									//Obtain the socket corresponding to the user from the map set according to the user name to which the message is to be forwarded
									Socket target=UserManager.getSocketByUsername(s[0]);
									OutputStream os=target.getOutputStream();
									byte[] messages=(UserManager.getUsername(address).getUsername()+
											"To you:"+s[1]).getBytes();
									os.write(messages);
											
								}
								
								//System.out.println(UserManager.getUsername(address) + "say" + MES);
							}else {
								
								OutputStream os=socket.getOutputStream();
								byte[] reply="Please log in first".getBytes();
								os.write(reply);
							
								
							}}
						}
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

		}
		
	}


class UserManager{
	//Save all logged in user information
	private static  Map<String, Customer> users=new HashMap<String, Customer>();
	
	//Log login information into the map collection
	public static void login(String address, Customer customer) {
		users.put(address, customer);
	}
	//Judge whether the user logs in
	public static boolean checkLogin(String address) {
		return users.containsKey(address);
	}
	//Return user name according to address
	public static Customer getUsername(String address) {
		
		return users.get(address);
	}
//Obtain the corresponding socket according to the user name
	public static Socket getSocketByUsername(String username) {
		Collection<Customer> customers=users.values() ;
		Socket target =null;
		for (Customer customer : customers) {
			if(customer.getUsername().equals(username)) {
				target=customer.getSocket();
			}
		}
		return target;
	}
	//Return all logged in users
	public static Collection<Customer> getAllCustomer() {
		return users.values();
	}
}
package qqserver;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

import sun.applet.Main;

public class MyServer  {
	
	public static void main(String[] args) throws Exception {
		//Create listening port
		ServerSocket ss=new ServerSocket(8998);
		//Call the accept method of the listening port object to receive the connection request from the client
		Socket socket;
		while(true){
			
			System.out.println("Ready to receive client connections");
			 socket=ss.accept();//Responsible for communicating with connected customers
			System.out.println("A client is connected:"+socket.getRemoteSocketAddress());
			
			//Create a thread that can receive port requests and messages at the same time
			ServerRecive sr=new ServerRecive(socket);
			sr.start();
			
			
			
		}
		
		
	
	}
	

}
package qqclient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class MyClient  {
	public static void main(String[] args) throws Exception {
		//Create a socket object and request to connect to the remote server
		Socket socket=new Socket("localhost",8998);
		
		//Create a thread to receive server replies
		ClientReceiver cr=new ClientReceiver(socket);
		cr.start();
		
		
		
		//Send message to client
		boolean flag=true;
		Scanner input=new Scanner(System.in);
		while(true) {
			while(flag) {
				System.out.println("Protocol: group chat prefix“ all:"Private chat "person name:", login“ login: "");
				flag=false;
				
			}
			System.out.println("Please enter a message:");
			String message=input.next();
			byte[] buffer=message.getBytes();
			
			//Use the output stream to send messages to the server
			OutputStream os=socket.getOutputStream();
			
			os.write(buffer);
		}
		
		
		
	}

}
class ClientReceiver extends Thread{
	private Socket socket;
	
	public ClientReceiver(Socket socket) {
		super();
		this.socket = socket;
	}

	@Override
	public void run() {
		try {
			while(true) {
				
				InputStream in=socket.getInputStream();
				byte[] buffer=new byte[1000];
				int r=in.read(buffer);
				System.out.println(new String(buffer,0,r));
			}
			
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}
package qqserver;

import java.net.Socket;

public class Customer {
	private String username;
	private Socket socket;
	public Customer(String username, Socket socket) {
		super();
		this.username = username;
		this.socket = socket;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Socket getSocket() {
		return socket;
	}
	public void setSocket(Socket socket) {
		this.socket = socket;
	}
	

}

Keywords: Java JavaEE network Multithreading NIO

Added by renob on Tue, 28 Dec 2021 13:59:45 +0200