Java Socket实现简易【单线程/多线程】的服务端与客户端的交互

今天复习了一下socket的知识,看了一些网上博客的代码,参考了一下自己也照着写了一个服务端与客户端的互撩demo

首先写一个客户端

package j2se;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
 
public class Server {
 
    public static void main(String[] args) {
    	
       try {
    	//初始化服务器端socket
		ServerSocket serverSocket=new ServerSocket(8888);
		//等待客户端连接
		System.out.println("等待连接");
		Socket socket=serverSocket.accept();
		System.out.println("服务器有连接进来了");
		
		
		//通过socket获取字符流
		BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		//获取输入的字符流
 	   	BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
		//获取客户端的输入流
		BufferedReader bufferedReader2=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
		String msg;
		
		while(true){
			msg=bufferedReader2.readLine();
			if("bye".equals(msg)||msg==null){
				System.out.println("服务器端消息:\n"+msg);
				System.out.println("聊天结束!");
				break;
			}
			System.out.println("来自客户端的消息:\n"+msg);
			
			System.out.println("服务器端输入:");
 		    String str = bufferedReader.readLine();
 		    bufferedWriter.write(str);
 		    bufferedWriter.write("\n");
 		    bufferedWriter.flush();
		}
		socket.close();
		bufferedReader.close();
		bufferedReader2.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
       
    }
}

然后是客户端,在字符流后面加上一个\n,作为标识告诉服务端客户端已经输入完了

package j2se;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
 
public class Client {
 
    public static void main(String[] args) {
 
       try {
    	   Socket socket=new Socket("127.0.0.1", 8888);
    	  
    	   
    	   //通过socket获取字符流
           BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    	   
    	   //获取输入的字符流
    	   BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
    	   //获取服务器端的字符流
    	   BufferedReader bufferedReader2=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
    	   
    	   while(true){
    		   System.out.println("客户端输入:");
    		   String str = bufferedReader.readLine();
    		   bufferedWriter.write(str);
    		   bufferedWriter.write("\n");
    		   bufferedWriter.flush();
    		   if("bye".equals(str)||str==null){
    			   System.out.println("聊天结束");
    			   break;
    		   }
    		   
    		   String msg=bufferedReader2.readLine();
    		   System.out.println("来自服务器端消息:\n"+msg);
    	   }
    	   socket.close();
    	   bufferedReader.close();
   		   bufferedReader2.close();
    	   
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
       
    }
}

分别运行起来

server

Java Socket实现简易【单线程/多线程】的服务端与客户端的交互_第1张图片

client

Java Socket实现简易【单线程/多线程】的服务端与客户端的交互_第2张图片 用“bye”作为聊天结束的标识,程序结束

Java Socket实现简易【单线程/多线程】的服务端与客户端的交互_第3张图片

但是这里可以看到,我们现在的程序是单线程的,同一时间,要么收消息,要么发消息,不能同时进行。

下面就做一点修改,用多线程实现同时收发。对上面代码做出修改,新增SendThread.java和ReceviceThread.java并且它们都继承了Thread

SendThread.java

package socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

public class SendThread extends Thread {
	private Socket socket;
	
	public SendThread(Socket socket){
	     this.socket = socket;
	}
	
	public void run(){
		try {
			//通过socket获取字符流
			BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		    //获取输入的字符流
		    BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
		    
		    while(true){
		    	System.out.println("请输入:");
	    		   String str = bufferedReader.readLine();
	    		   bufferedWriter.write(str);
	    		   bufferedWriter.write("\n");
	    		   bufferedWriter.flush();
	    		   if("bye".equals(str)||str==null){
	    			   System.out.println("聊天结束");
	    			   break;
	    		   }
		    }
		   
		}  catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

ReceviceThread.java

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class ReceviceThread extends Thread {
	private Socket socket;
	 
    public ReceviceThread(Socket socket) {
        this.socket = socket;
    }
    
    public void run(){
    	try {
			//获取客户端的输入流
			BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
			String msg;
			while(true){
				msg=bufferedReader.readLine();
				if("bye".equals(msg)||msg==null){
					System.out.println("收到消息:\n"+msg);
					System.out.println("聊天结束!");
					break;
				}
				System.out.println("收到消息:\n"+msg);
			}
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }

}

重新修改Server.java

package socket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			ServerSocket serverSocket=new ServerSocket(8888);
			//等待客户端连接
			System.out.println("等待连接");
			Socket socket=serverSocket.accept();
			System.out.println("服务器有连接进来了");
			
			//启动发送消息线程
            new SendThread(socket).start();
            //启动接受消息线程
            new ReceviceThread(socket).start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

Client.java

package socket;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			Socket socket=new Socket("127.0.0.1",8888);
			// 启动发送消息线程
            new SendThread(socket).start();
            // 启动接受消息线程
            new ReceviceThread(socket).start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

在控制台看到,我们可以一直向服务端发送消息,服务端也能一直受到消息或者发送消息

Java Socket实现简易【单线程/多线程】的服务端与客户端的交互_第4张图片

Java Socket实现简易【单线程/多线程】的服务端与客户端的交互_第5张图片

你可能感兴趣的:(Demo)