本文计划采用socket实现客户端和服务端的任意双向通信,即客户端可以随时给服务端发消息,服务端也可以随时给客户端发消息,最终结果就是一个类似与QQ的聊天软件的功能。

以下代码可以直接拷贝到Eclipse中运行。

前面的两片文章都利用了socket实现了客户端与服务器的通信,我的前两片文章:

Java中利用socket实现简单的服务端与客户端的通信(入门级),实现了一个简单的客户端发送消息,服务器端接收消息的实力,没有多线程,也没有让服务器端有消息返回。

Java中利用socket实现简单的服务端与客户端的通信(基础级),在上一篇的基础上,在服务端实现了多线程,使得服务端可以于多个客户端连接并接收他们发送的消息。

要想实现任意的双向通信,以客户端来说,时刻既需要能够发送消息,同时也需要能够随时的接收服务端发来的消息,这两个功能必须同时存在,还必须同时运行,所以这个时候就必须使用到多线程了。无论是服务端还是客户端,都至少需要多出两个线程,一个线程用于发送数据,一个线程用于接收数据。这是本文的关键。

客户端:

package client_3;import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;  public class client_3 {  public static final String IP = "localhost";//服务器地址   public static final int PORT = 10000;//服务器端口号    public static void main(String[] args) {handler();   }  private static void handler(){  try {      //实例化一个Socket,并指定服务器地址和端口  Socket client = new Socket(IP, PORT);  System.out.println("I am a client");    //开启两个线程,一个负责读,一个负责写  new Thread(new ReadHandlerThread(client)).start();  new Thread(new WriteHandlerThread(client)).start();  } catch (Exception e) {  e.printStackTrace();  }  }
}    /*  *处理读操作的线程   */
class ReadHandlerThread implements Runnable{  private Socket client;  public ReadHandlerThread(Socket client) {  this.client = client;  }  @Override  public void run() {  BufferedReader in = null;try {in = new BufferedReader(new InputStreamReader(client.getInputStream()));} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try {  while(true){ System.out.println("服务器说:"+in.readLine());    }  } catch (IOException e) {  e.printStackTrace();  } finally{              if(client != null){  client = null;  }  }  }
}  /*  * 处理写操作的线程  */
class WriteHandlerThread implements Runnable{  private Socket client;  public WriteHandlerThread(Socket client) {  this.client = client;  }  @Override  public void run() {  PrintWriter out=null;try {out = new PrintWriter(client.getOutputStream());} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}                 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));//从控制台获取输入的内容  try {  while(true){  out.println(reader.readLine());  out.flush();}  } catch (IOException e) {  e.printStackTrace();     }try {client.close();reader.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}out.close();}
}  

可以看到,上述代码有两个线程类,一个负责读,一个负责写,同样的,服务端的代码也大同小异。

服务端:

package server_3;import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;  public class server_3 {  public static final int PORT = 10000;//监听的端口号     public static void main(String[] args) {    System.out.println("sever begins");server_3 server = new server_3();    server.init();    }    public void init() {    ServerSocket serverSocket = null;  try {    serverSocket = new ServerSocket(PORT);    while (true) {    Socket client = serverSocket.accept();    //一个客户端连接就开两个线程分别处理读和写    new Thread(new ReadHandlerThread(client)).start();    new Thread(new WriteHandlerThread(client)).start();   }    } catch (Exception e) {    e.printStackTrace();    } finally{  try {  if(serverSocket != null){  serverSocket.close();  }  } catch (IOException e) {  e.printStackTrace();  }  }  }
}    /*  *处理读操作的线程   */
class ReadHandlerThread implements Runnable{  private Socket client=null;  public ReadHandlerThread(Socket client) {  this.client = client;  }  @Override  public void run() {  BufferedReader in = null;try{  while(true){  //读取客户端数据    in = new BufferedReader(new InputStreamReader(client.getInputStream()));System.out.println("客户端说:" + in.readLine());   }  }catch(Exception e){  e.printStackTrace();  }finally{  if(client != null){  client = null;  }  }  }
}  /*  * 处理写操作的线程  */
class WriteHandlerThread implements Runnable{  private Socket client;  public WriteHandlerThread(Socket client) {  this.client = client;  }  @Override  public void run() {  PrintWriter out=null;try {out = new PrintWriter(client.getOutputStream());} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}  BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));//从控制台获取输入的内容 try{  while(true){  //向客户端回复信息    out.println(reader.readLine());out.flush();  }  }catch(Exception e){  e.printStackTrace();  }finally{  if(client != null){  client = null;  }  }  }
}  

以上程序,先启动服务端,再启动客户端,就可以实现两端的任意聊天,功能和qq等软件类似。

2015年11月26日   西安交通大学

Java中利用socket实现简单的服务端与客户端的通信(中级)——实现任意双向通信相关推荐

  1. Java中利用socket实现简单的服务端与客户端的通信(基础级)

    在上一篇文章中,简单的介绍了java中入门级的socket编程,简单的实现了客户端像服务器端发送数据,服务器端将数据接收并显示在控制台,没有涉及多线程.上一篇文章的链接:Java中利用socket实现 ...

  2. Java中利用socket实现简单的服务端与客户端的通信(入门级)

    Java编程中,要想要使用网络通信,就离不开Socket编程,在此对socket进行简单的介绍.首先声明,这是一个入门级的介绍,仅仅简单的实现了客户端向服务端发送数据,服务端正常的接收数据,当接收到特 ...

  3. SpringBoot(23) 集成socket.io服务端和客户端实现通信

    一.前言 websocket和socket.io区别? websocket 一种让客户端和服务器之间能进行双向实时通信的技术 使用时,虽然主流浏览器都已经支持,但仍然可能有不兼容的情况 适合用于cli ...

  4. socket.io服务端是java_SpringBoot(23) 集成socket.io服务端和客户端实现通信

    @Slf4j @Service(value = "socketIOService") public class SocketIOServiceImpl implements ISo ...

  5. axis idea 设置apache_利用IDEA创建Web Service服务端和客户端的详细过程

    创建服务端 一.file–>new–>project 二.点击next后输入服务端名,点击finish,生成目录如下 三.在 HelloWorld.Java 文件中右击,选 WebServ ...

  6. Java实现服务端和客户端的通信(文件下载)

    网络编程 网络通信的介绍 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据 两台电脑连在一起就组成了一个计算机网络.我们通过光纤连接到电信的网关,中国电信通过海底光缆和美国电信网关连接,你 ...

  7. windows Socket编程之TCP服务端与客户端

    在前面的文章中有一篇讲到了命名管道通信,它是创建一根管道来进行进程之间或网络之间通信的.但是它有些缺陷,比如说效率较低等.而从这篇文章开始将介绍socket编程.socket是通过TCP,UDP,IP ...

  8. Winform中使用MQTTnet实现MQTT的服务端和客户端之间的通信以及将订阅的消息保存到文件

    场景 MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻 ...

  9. 简单的c++服务端与客户端的通信

    本篇博客是本人没有深入学习网络通信,对其浅浅的了解了一下,只知道怎么连接以及发送内容,若内容有什么错误的地方还麻烦各位大佬可以指出来大家一起讨论一下.   服务端代码如下: #include < ...

最新文章

  1. IDEA中Maven项目创建单元测试(JUnit4)
  2. 关于同时可用git命令clone和TortoiseGit拉取代码不需要密码
  3. python批量访问网页保存结果_Python检测批量URL状态,并将返回正常的URL保存文件...
  4. Intellij IDEA 2017 如何导入 GitHub 中的项目
  5. F5解决方案– 教育行业解决方案1(分析篇)
  6. 开源方案搭建可离线的精美矢量切片地图服务-6.Mapbox之.pbf字体库
  7. iOS-NSUserDefaults缓存自定义对象
  8. java程序打包exe
  9. 20172304 《程序设计与数据结构》 第一周学习总结
  10. 织梦友情链接html,总结dedecms怎么调用友情链接的方法[全]
  11. MDM平台数据分发功能说明
  12. 惟伊·京汉方邀约全国贵宾黄龙溪一日游
  13. ppt制作的一些要点
  14. Aseprite入门教程
  15. 读Python源码(三)Python列表的表示
  16. open、write、read函数总结(初学者,请见谅)
  17. 8/4 奈奎斯特采样定理(香农采样定理)
  18. 以太网实习_网络工程-实习报告及
  19. 2023年Unity UI教程
  20. Linux文件系统(四)文件缓存

热门文章

  1. reactor官方文档译文(1)Reactor简介
  2. cp: omitting directory”错误
  3. 【机器学习】ROC曲线和PR(Precision-Recall)曲线的联系
  4. 【机器学习】什么是机器学习?(上)
  5. 基于Java语言构建区块链(四)—— 交易(UTXO)
  6. 神经网络贷款风险评估(base on keras and python ) 原创 2017年08月18日 14:35:17 标签: python / 神经网络 / keras 300 用我
  7. GMIS 2017 大会余凯演讲:深度学习引领驾驶革命
  8. 随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比
  9. 如何设置mysql让其他人能访问_怎么配置MySQL数据库让别人远程访问
  10. 白话Elasticsearch15-深度探秘搜索技术之使用copy_to定制组合field解决cross-fields搜索弊端