先来看一段单线程的原始代码(代码中有详细的注释):

         服务器(TCPServer.java):

import java.net.*;
import java.io.*;public class TCPServer{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(5566); //创建一个Socket服务器,监听5566端口int i=0;//利用死循环不停的监听端口while(true){Socket s = ss.accept(); //利用Socket服务器的accept()方法获取客户端Socket对象。i++;System.out.println("第" + i +"个客户端成功连接!");DataInputStream dis = new DataInputStream(s.getInputStream()); //获取客户端Socket对象的输入流,并在外边加一层DataInputStream管道,目的是方便读取数据System.out.println(dis.readUTF()); //读出流中的数据,DataInputStream对象的readUTF()方法可以读出流中的数据,而且支持中文dis.close(); //关闭管道连接s.close(); //关闭Socket连接}}}

        客户端(TCPClient.java):

import java.net.*;
import java.io.*;public class TCPClient{public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.24.177",5566); //创建一个Socket对象,连接IP地址为192.168.24.177的服务器的5566端口DataOutputStream dos = new DataOutputStream(s.getOutputStream()); //获取Socket对象的输出流,并且在外边包一层DataOutputStream管道,方便输出数据dos.writeUTF("客户端消息"); //DataOutputStream对象的writeUTF()方法可以输出数据,并且支持中文dos.flush(); //确保所有数据都已经输出dos.close(); //关闭输出流s.close(); //关闭Socket连接}
}

        以上代码利用Socket对象和ServerSocket对象进行简单的网络交互,即客户端通过DataOutputStream对象的writeUTF()方法向服务器发送消息,服务器利用DataInputStream对象的readUTF()方法读出数据。

        看上去挺好,但ServerSocket对象的accept()方法是阻塞的方法,它会一直等待,直到有客户端连接。

        同理,DataInputStream对象的readUTF()方法也是阻塞的方法,它也会一直等待,直到客户端调用writeUTF()方法。

        因此,假如某个客户端成功连接服务器,但是迟迟不调用writeUTF()方法发送数据,服务器就要一直等待,直到客户端调用writeUTF()方法为止,此期间整个服务器是阻塞的,无法再接受其他客户端连接,显然这不符合实际情况。

        要解决这个问题,当然要用多线程。

        如果每个客户端都独有一个线程,让readUTF()方法阻塞客户端独有的线程,而不去阻塞服务器主线程,这样服务器就可以同时接受多个客户端连接,而不用考虑客户端何时调用writeUTF()方法发送数据。代码如下:

        服务器(TCPServer.java):

import java.net.*;
import java.io.*;public class TCPServer{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(5566); //创建一个Socket服务器,监听5566端口int i=0;//利用死循环不停的监听端口while(true){Socket s = ss.accept();//利用Socket服务器的accept()方法获取客户端Socket对象。i++;System.out.println("第" + i +"个客户端成功连接!");Client c = new Client(i,s); //创建客户端处理线程对象Thread t =new Thread(c); //创建客户端处理线程t.start(); //启动线程}}}//客户端处理线程类(实现Runnable接口)
class Client implements Runnable{int clientIndex = 0; //保存客户端idSocket s = null; //保存客户端Socket对象Client(int i,Socket s){clientIndex = i;this.s = s;}public void run(){//打印出客户端数据try{DataInputStream dis = new DataInputStream(s.getInputStream());System.out.println("第" + clientIndex + "个客户端发出消息:" + dis.readUTF());dis.close();s.close();}catch(Exception e){}}
}

        客户端(TCPClient.java):

import java.net.*;
import java.io.*;public class TCPClient{public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.24.177",5566); //创建一个Socket对象,连接IP地址为192.168.24.177的服务器的5566端口DataOutputStream dos = new DataOutputStream(s.getOutputStream()); //获取Socket对象的输出流,并且在外边包一层DataOutputStream管道,方便输出数据Thread.sleep((int)(Math.random()*3000)); //让客户端不定时向服务器发送消息dos.writeUTF("客户端消息"); //DataOutputStream对象的writeUTF()方法可以输出数据,并且支持中文dos.flush(); //确保所有数据都已经输出dos.close(); //关闭输出流s.close(); //关闭Socket连接}
}

        运行结果如下(参考结果,不一定相同!):

        明显看出第2、3、4客户端都没有向服务器端发出消息,但都成功连接,而且第2、3、4客户端向服务器发出消息也没有顺序。

        通过多线程,实现了多个客户端同时连接服务器,并且服务器能实时处理多个客户端发出的消息。

        以上仅仅是作为初学者的一些想法,仅供参考!

简单模拟多线程Socket通信(java)相关推荐

  1. 多线程socket通信server

    控制台下实现多线程socket通信,服务端为每个请求的客户端创建一个线程,进行通信.其实这些MSDN里都有. 一.基本流程如下: 定义变量->获得winsock版本->加载winsock库 ...

  2. 银企直联与前置机socket通信-Java

    银企直联一般都是通过前置机与银行服务进行通信,企业服务 前置机 银行三者关系如下 在企业应用在这里就相当于客户端,前置机就相当服务端 ERP 与 CT 之间的交易数据报文采用 TCP/IP 协议的 S ...

  3. C# Socket系列二 简单的创建 socket 通信

    看了系列一 我们开启了对socket tcp的监听状态,那么这一章我们来讲解怎么创建socket的通信代码 我新建一个类 TSocketBase public abstract class TSock ...

  4. 基于Java NIO的Socket通信

    基于Java NIO的Socket通信 Java NIO模式的Socket通信,是一种同步非阻塞IO设计模式,它为Reactor模式实现提供了基础. 下面看看,Java实现的一个服务端和客户端通信的例 ...

  5. 嵌入式开发日记(9)——多线程与socket通信

    尝试用多线程,socket网络编程,心跳检测机制,实时绘图,丢包检测机制,校验位检测,超时重传机制,  数据库存储等功能优化项目 多线程与socket编程: 参考链接: https://blog.cs ...

  6. java与C语言之间socket通信(java客户端 C服务端)

    直接贴代码 服务端C代码 server.c #include <stdio.h> #include <sys/types.h> #include <sys/socket. ...

  7. java 通信 教程_Java实现简单的socket通信教程

    今天学习了一下java如何实现socket通信,感觉难点反而是在io上,因为java对socket封装已经很完善了. 今天代码花了整个晚上调试,主要原因是io的flush问题和命令行下如何运行具有pa ...

  8. java socket建立长连接_Java Web项目中使用Socket通信多线程、长连接的方法

    很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听.我们的应用场景是在java项目中,需要外接 ...

  9. java socket通信 客户端_JavaのSocket编程之简单客户端与服务器端通信

    Socket编程之简单客户端与服务器端通信 socket 通常用来实现客户端和服务端的连接,socket 是Tcp/Ip协议的一个十分流行的编程界面,一个socket 由一个Ip地址和一个端口号唯一确 ...

最新文章

  1. 成功解决A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,co
  2. 如何避免HBase写入过快引起的各种问题
  3. python pygame模块怎么写游戏_使用 Python 和 Pygame 模块构建一个游戏框架
  4. DB2 pureScale在线备份恢复实例1
  5. 操作系统--用户级线程与内核级线程
  6. Less or Equal(CF-977C)
  7. mysql 时间函数大全_mysql常用的日期函数汇总
  8. keras报错ModuleNotFoundError: No module named ‘keras.backend.tensorflow_backend‘;
  9. CouchBase C 客户端接口调用实例
  10. LabView学习笔记(六):while循环与for循环
  11. 设计模式七大原则简述
  12. JavaScript实用代码片段
  13. python中的位置怎么看_如何获得字符在Python中的位置?
  14. Linux 句柄是什么
  15. 计算机网络数据通信部分之网络层IP报文格式解析
  16. 数控技术 - 直线插补 - 逐点比较法
  17. UA MATH564 概率论 概率不等式
  18. bzoj4816: [Sdoi2017]数字表格
  19. 互联网金融VS区块链金融
  20. LeCo-82.删除排序链表中的重复元素(二)

热门文章

  1. windows 2008 server 各版本功能差异
  2. 3G 资费 流量套餐
  3. Exchange2003反病毒
  4. [原创]利用WM_COPYDATA实现进程间通信
  5. Android的activity的title设定内容
  6. 使用UInput模拟系统键盘鼠标动作 UInput driver分析
  7. Java Vistor 设计模式
  8. CSS实现返回网页顶部
  9. 基于live555开发嵌入式linux系统的rtsp直播服务
  10. 如何在windows中使用cmd命令去编译,运行C++程序