博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单模拟多线程Socket通信(java)
阅读量:4518 次
发布时间:2019-06-08

本文共 3420 字,大约阅读时间需要 11 分钟。

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

 

         服务器(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; //保存客户端id  Socket 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客户端向服务器发出消息也没有顺序。

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

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

转载于:https://www.cnblogs.com/iyangyuan/archive/2012/09/03/2801811.html

你可能感兴趣的文章
JSON日期时间格式转换
查看>>
《计算机组成结构化方法》读书笔记-1
查看>>
jquery 导航固定的一个实例
查看>>
go语言调用cmd
查看>>
jQuery中.bind() .live() .delegate() .on()区别
查看>>
暑假第五测
查看>>
怪盗基德的滑翔翼
查看>>
Markdown 的离线编辑工具推荐:Sublime Text3 or Typora?我推荐Typora
查看>>
Mac添加或修改环境变量
查看>>
P2173 [ZJOI2012]网络
查看>>
P1484 种树
查看>>
CodeForces 566 D.Restructuring Company
查看>>
方格填数
查看>>
Flash Professional中运行ActionScript类
查看>>
直通BAT面试算法精讲课1
查看>>
运行期异常与编译期异常区别
查看>>
STM32使用注意事项
查看>>
第十万零二个素数
查看>>
前端笔记之Vue(七)Vue-router&axios&Vue插件&Mock.js&cookie|session&加密
查看>>
【C++】C++运行环境的搭建
查看>>