JAVA套接字实现简易的双人通信系统

JAVA套接字实现简易的双人通信系统

JAVA套接字资料

socket是基于应用服务与TCP/IP通信之间的一个抽象,他将TCP/IP协议里面复杂的通信逻辑进行分装,对用户来说,只要通过一组简单的API就可以实现网络的连接。借用网络上一组socket通信图给大家进行详细讲解:

首先,服务端初始化ServerSocket,然后对指定的端口进行绑定,接着对端口及进行监听,通过调用accept方法阻塞,此时,如果客户端有一个socket连接到服务端,那么服务端通过监听和accept方法可以与客户端进行连接。

以上资料:

作者:长道
链接:https://www.jianshu.com/p/cde27461c226
来源:简书

解决方案

综上所述,JAVA套接字需要一个SeverSocket对象作为服务端,监听Socket的连接请求,需要一个Socket对象作为客户端,向SeverSocket发送连接的请求。客户端和服务端建立连接后为全双工,两端均可接收和发送数据,接收和发送可以用流来实现。所以用SeverSocket和Socket分别作为两端进行通信。
但是如果两端仅仅用while循环来不停的发送和接收数据会发生阻塞,原因是因为一端只有完成发送操作后,才能开始接收操作,而键盘读取字符串的函数是阻塞的,socket流的读操作也会发生阻塞,所以只有键盘输入并按下回车,程序才会继续执行,另一端也相同。最终造成的结果是两端每次只能说一句话,说完后必须等待,只有接收到对方发来信息后,才可也说下一句。
解决方法就是利用多线程,服务端和客户端都设置两个线程,一个线程专门用来接收信息,一个专门用来发送信息。这样,接收和发送互不影响,消除阻塞。

主要代码块

服务端,接收客户端的连接请求,创建新的线程:

客户端,请求连接,并创建新的线程:

接收的线程:不断从输入流读取数据并打印

发送的线程:不断从键盘读取字符串并写入输出流

客户端和服务端的接收和发送进程基本相同

运行结果

最终代码

服务端

package com;

import java.io.IOException;
import java.io.*;
import java.net.*;
import java.util.Scanner;

public class Server{
	static ServerSocket serverSocket;
	public static void main(String[] args) {
		try {
			serverSocket = new ServerSocket(1515);
			while(true) {
				Socket accept_client = serverSocket.accept(); 
				new Thread(new ServerIn(accept_client)).start();
				new Thread(new ServerOut(accept_client)).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
			try {
				serverSocket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
}
//接受的线程
class ServerIn implements Runnable{
	Socket socket;
	
	ServerIn(Socket socket){
		this.socket = socket;
	}
	@Override
	public void run() {
		try {
			InputStream in = socket.getInputStream();
			while(true) {
				byte infile[] = new byte[1024];
				int size  = in.read(infile);
				String string = new String(infile,0,size);
				if(!string.equals("") && !string.equals("\n")) System.out.println("message from client: "+ string);
			}
		} catch (IOException e) {
			e.printStackTrace();
			try {
				socket.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}
}
//发送的线程
class ServerOut implements Runnable{
	Socket socket;
	Scanner reader = new Scanner(System.in);
	ServerOut(Socket socket){
		this.socket = socket;
	}
	public void run() {
		try {
			OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
			while(true) {
				String string  = reader.nextLine();
				out.write(string);
				out.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
			try {
				socket.close();
				reader.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}	
}

客户端

package com;

import java.io.*;
import java.util.*;
import java.net.*;

public class Client{
	public static void main(String[] args) {
		try {
			Socket client = new Socket("127.0.0.1",1515);
			new Thread(new ClientIn(client)).start();
			new Thread(new ClientOut(client)).start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
//接受的线程
class ClientIn implements Runnable{
	Socket socket;
	ClientIn(Socket socket){
		this.socket = socket;
	}
	@Override
	public void run() {
		try {
			InputStream in = socket.getInputStream();
			while(true) {
				byte infile[] = new byte[1024];
				int size = in.read(infile);
				String string = new String(infile,0,size);
				if(!string.equals("") && !string.equals("\n")) System.out.println("message from server: "+ string);
			}
		} catch (IOException e) {
			e.printStackTrace();
			try {
				socket.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}
	
}
//发送的线程
class ClientOut implements Runnable{
	Socket socket;
	Scanner reader = new Scanner(System.in);
	ClientOut(Socket socket){
		this.socket = socket;
	}
	public void run() {
		try {
			OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
			while(true) {
				String string  = reader.nextLine();
				out.write(string);
				out.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
			try {
				socket.close();
				reader.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}
}

计算1913 李文轩

posted @ 2020-12-30 22:32  MmmelodyyY  阅读(195)  评论(0)    收藏  举报