温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

JAVA如何实现基于Socket的多线程通信

发布时间:2021-10-15 13:46:52 来源:亿速云 阅读:142 作者:小新 栏目:编程语言

这篇文章主要介绍了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的多线程通信”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI