`
wsql
  • 浏览: 11776422 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

简单模拟多线程Socket通信(java)

 
阅读更多

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

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

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

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


分享到:
评论

相关推荐

    java实现socket多线程。模拟实现通过使用多个WiFi模块+串口助手进行数据发送,采用socket协议,接收数据进行解析

    2. 实现socket多线程,监听端口1314,最大socket队列100,都可以人为设置 3. 模拟了对串口助手发送来的一串十六进制数据进行解析 4. 使用串口助手发送数据,模拟数据如图“模拟数据.png”所示 爱吃凉拌辣芒果 ...

    Java Socket 聊天程序(图形界面)

    实现Java Socket聊天多线程编程,图形化界面,多人聊天(群聊),私人聊天,是基于本地模拟的Java聊天程序。 Java Socket聊天程序是我用了三天的时间写出来,用Netbeans建的工程,图形化界面是Netbeans拖拉出来的,...

    简易聊天程序_java网络编程多线程

    java编译的控制台版多人简易聊天程序,运用了ServerSocket和Socket网络编程,还用了多线程,I/O流等技术.可以私聊,可以群聊!

    三个 java socket服务器客户端通信例子

    例子都可以跑通均已测试通过 com.socket 包中是一个简单的客户端发给服务器的例子 com.socket.complex 使用多线程来模拟通信 com.socket.block 根据客户端传递的参数来返回不同的信息

    多线程实现的简单网络聊天程序,带注释

    简单的网络聊天程序,用多线程实现数据接收,带详细的注释,可以给初学者学习

    javaswing 模拟QQ聊天

    自己做的javaswing作业 模拟QQ聊天工具 进行多线程通信

    java模拟数据库事务

    用java来模拟事务间的并发处理 后台是用文件存储来模拟数据库数据 用到的技术有: 1) java Socket通信 2) java多线程缓冲 3) 各重java设计模式

    基于Socket的Android聊天室

    Socket通信是网络通信中最常用的技术之一,通过Socket建立的可靠连接,可以让多个终端与服务器保持通信,最典型的应用是建立一个多人聊天程序。本实例使用ServerSocket建立聊天服务器。将服务器端所有的通讯线程保存...

    ATM模拟ATM机系统.zip

    模拟ATM机系统的登陆、显示个人信息、存取款等基本功能。 1. 图形用户界面,要有登陆界面,主界面有菜单; 2. 连接MySQL数据库;... 3. 实现存、取款,查询余额、显示个人信息等功能。 4. socket通信,多线程;

    Java案例开发锦集

    案例3 用JDOM解析XML文件 案例4 Java编制的时钟 案例5 简单日历 案例6 系统内存状态监视程序 案例7 简单计算器 案例8 多线程断点续传 案例9 笛卡尔曲线 第四章 Java与游戏 案例1 ...

    java源码包---java 源码 大量 实例

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    socket通信例子

    主要是模拟通信。。多个前台可以向后台发送信息。后台可以读出来!

    JAVA上百实例源码以及开源项目源代码

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    java源码包4

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    Android学习笔记含JNI、USB和ftdi通信方式详解

    项目四 多线程文件下载 25 项目五 Android自定义树形菜单 26 项目六 高仿微信聊天 26 项目七 Android串口通信 26 1. Java层 26 2.JNI层 26 3.PC模拟MCU层 26 4.问题 26 1. arm串口通信问题 26 2. linux串口通信中...

    java源码包3

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    JAVA上百实例源码以及开源项目

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    java源码包2

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    分布式中央空调系统从控机

    java语言编写的具有模拟环境温度,socket通信,多线程处理,日志记录等功能的空调从控机,代码原创

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java局域网通信——飞鸽传书源代码 28个目标文件 内容索引:JAVA源码,媒体网络,飞鸽传书 Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java...

Global site tag (gtag.js) - Google Analytics