socket java 多线程_简单模拟多线程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连接

}

}

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

1346635999_1989.png

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值