这篇文章主要介绍了JAVA如何实现基于Socket的多线程通信,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
代码简介
代码思想:
实现"服务端-客户端"之间的通信需要解决两点问题
(1),如何实现通信
(2),通信中如何避免单线程先接收后发送(或先发送后接收)的问题;
解决方案:
(1),实现通信:使用ServerSocket监听指定端口后,Socket进行连接;然后客户端与服务端都获取Socket对象的输入输出流存入PrintWrite后不断刷新,即可实现通信;
(2),弥补单线程缺陷:创建消息接收类和消息发送类分别继承Thread;然后通过开启两个线程完避免单线程必须先接收后发送(或先发送后接收)的问题;
服务端
package x_Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class x_Server{
/** 声明全局对象,让x_Server的内部类可以共同调用这些对象 **/
static ServerSocket serverSocket = null;//声明静态全局的socket类对象;让x_Server的静态方法可以直接调用该对象;
static Socket socket = null; //声明静态全局的socket类对象;让x_Server的静态方法可以直接调用该对象;
BufferedReader buffSend = null; //信息发送数据流
BufferedReader buffReciever = null; //信息接收数据流
PrintWriter printWriter = null; //数据读写数据流
/** 主函数入口 **/
public static void main(String[] args) throws IOException {
serverSocket = new ServerSocket(5556); //通过Socket的构造函数,监听的5556端口(即等待socket对象向该端口请求连接)
socket = serverSocket.accept(); //如果有socket的对象请求连接了5556端口,则serverSocket的accept返回一个socket对象;
System.out.println("有用户成功连接客户端");
Thread xsend = new Thread(new x_Server().new x_Send()); //通过Thread类的构造函数,创建一个x_Send类的线程对象
Thread xreciver = new Thread(new x_Server().new x_Receiver()); //通过外部类对象去实例化内部类,再通过Thread的构造函数,创建内部类x_Reciever的线程二对象;
xsend.start(); //启动x_Send的线程,让发送与接收数据可以同时进行
xreciver.start(); //启动x_Receiver的线程,让发送与接收数据可以同时进行
}
/** 用于服务端发送信息的x_Send类(线程一) **/
class x_Send extends Thread{
public void run(){ //继承Thread类,必须重写run()方法
try {
buffSend = new BufferedReader(new InputStreamReader(System.in));//获取从控制台输入数据的对象buffSend
printWriter = new PrintWriter(socket.getOutputStream()); //通过PrintWriter类的构造方法,获取向客户端发送信息的输出流对象
String msg = null; //msg:存储服务端发送的信息
do{
msg = buffSend.readLine(); //获得从控制台输入一行的信息
printWriter.println(msg); //将msg传到向服务端发送信息的输出流对象
printWriter.flush(); //刷新输入输出流,客户端端可以立刻收到输入输出流的更新信息
}while(!msg.equals("end")); //客户输入"end"表示结束通信
socket.close(); //关闭端口5556的连接
serverSocket.close(); //不再监听端口5556(即不再接收来自该端口的连接)
} catch (IOException e) {
System.out.println("客户端连接已断开");
e.printStackTrace();
}
}
}
/** 用于服务端接收信息的x_Reciever类(线程二) **/
class x_Receiver extends Thread{
public void run(){ //继承Thread类,必须重写run()方法
try {
buffReciever = new BufferedReader(new InputStreamReader(socket.getInputStream())); //获取从socket输入(客户端传输过来)数据的输入流对象
while(true){
System.out.println("接收客户端消息:"+buffReciever.readLine()); //输出客户端传输过来的信息
}
} catch (IOException e) {
System.out.println("客户端连接已断开:\n");
e.printStackTrace();
}
}
}
}
客户端
package x_Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class x_Client {
/** 声明全局对象,让x_Client的内部类可以共同调用这些对象 **/
static Socket socket = null; //声明静态全局的socket类对象;让x_Client的静态方法可以直接调用该对象;
BufferedReader buffSend = null; //信息发送数据流
BufferedReader buffReciever = null; //信息接收数据流
PrintWriter printWriter = null; //数据读写数据流
/** 主函数入口 **/
public static void main(String[] args) throws UnknownHostException, IOException {
socket =new Socket("127.0.0.1",5556); //通过Socket的构造函数,连接本地ip的5556端口
System.out.println("连接服务端信息如下:\nip:127,0.0.1 port:5556");
Thread xsend = new Thread(new x_Client().new x_SendMsg()); //通过Thread类的构造函数,创建一个x_SendMsg类的线程对象
Thread xreciver = new Thread(new x_Client().new x_RecieverMsg()); //通过外部类对象去实例化内部类,再通过Thread的构造函数,创建内部类x_RecieverMsg的线程二对象;
xsend.start(); //启动x_SendMsg的线程;
xreciver.start(); //启动x_RecieverMsg的线程;两个让发送与接收数据可以同时进行
}
/** 用于客户端发送信息的x_SendMsg类(线程一)**/
class x_SendMsg extends Thread{
public void run(){ //继承Thread类,必须重写run()方法
try {
buffSend = new BufferedReader(new InputStreamReader(System.in));//获取从控制台输入数据的对象buffSend
printWriter = new PrintWriter(socket.getOutputStream()); //通过PrintWriter类的构造方法,获取向服务端发送信息的输出流对象
String msg = null; //msg:存储客户端发送的信息
do{
msg = buffSend.readLine(); //获得从控制台输入一行的信息
printWriter.println(msg); //将msg传到向服务端发送信息的输出流对象
printWriter.flush(); //刷新输入输出流,服务端可以立刻收到输入输出流的更新信息
}while(!msg.equals("end")); //客户输入"end"表示结束通信
socket.close(); //关闭端口5556的连接
} catch (IOException e) {
System.out.println("服务端端口已关闭"); //异常提示信息显示
e.printStackTrace(); 郑州祛胎记医院哪家好 http://www.zykeda120.com/
}
}
}
/** 用于客户端接收信息的x_RecieverMsg类(线程二) **/
class x_RecieverMsg extends Thread{
public void run(){ //继承Thread类,必须重写run()方法
try {
buffReciever = new BufferedReader(new InputStreamReader(socket.getInputStream())); //获取从socket输入(服务端传输过来)数据的输入流对象
while(true){
System.out.println("收到服务端消息:"+buffReciever.readLine()); //输出服务端传输过来的信息
}
} catch (IOException e) {
System.out.println("服务端端口已关闭"); //异常提示信息显示
e.printStackTrace();
}
}
感谢你能够认真阅读完这篇文章,希望小编分享的“JAVA如何实现基于Socket的多线程通信”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。