java socket 客户端接收_java socket多客户端简单示例

因为有多线程的存在,所以当连接请求到达时,可以在服务端创建多个socket,分别和不同的客户端进行连接通信。

服务端

SocketServerRelease 用于不断接收客户端的连接,并创建socket

public class SocketServerRelease extends Thread{

public static ServerSocket server = null;

static{

try {

server = new ServerSocket(5209);

} catch (IOException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

System.out.println("******服务器已启动,等待客户端连接*****");

Socket socket = null;

int i=1;

try {

while(true){

//循环监听客户端的连接

socket = server.accept();

//新建一个线程ServerSocket,并开启

System.out.println("开启第"+i+"个socket");

new SocketServerThread(socket,"第"+i+"个socket").start();

i++;

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

SocketServerThread 接收和发送消息处理

public class SocketServerThread extends Thread{

private Socket socket;

private String name;

public SocketServerThread(Socket socket,String name) {

this.socket = socket;

this.name = name;

}

@Override

public void run() {

Accepter accepter = new Accepter(socket,name);

Sender sender = new Sender(socket,name);

accepter.start();

sender.start();

}

class Accepter extends Thread{

private Socket socket;

private String name;

public Accepter(Socket socket,String name) {

this.socket = socket;

this.name = name;

}

@Override

public void run() {

String message="";

try {

BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream()));;

int i=1;

do{

message = in.readLine();

System.out.println("服务端第"+i+"次接收到来自<>信息为:"+message);

i++;

}while (!"exit".equals(message));

//当客户端输入exit退出后,关闭socket输入流

//in.close(); //这种关闭流的方法会导致socket关闭

socket.shutdownInput();

System.out.println("服务端已停止接收<>的数据");

} catch (IOException e) {

e.printStackTrace();

}

}

}

class Sender extends Thread{

private Socket socket;

private String name;

public Sender(Socket socket,String name) {

this.socket = socket;

this.name = name;

}

@Override

public void run() {

int i= 1;

String readLine = "";

try {

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

PrintWriter writer = new PrintWriter(socket.getOutputStream());

do{

readLine = br.readLine();

if(null != readLine){

writer.println(readLine);

writer.flush();

}

System.out.println("服务端第"+i+"次发送信息给<>,信息为:"+readLine);

i++;

}while (!"exit".equals(readLine));

//br.close(); //注意这里的控制台输入流不能关闭,在多线程的情况下有可能出现A线程正在读,而B线程已经关闭了该流的情况

//writer.close(); //采用流关闭方式会导致socket关闭

socket.shutdownOutput();

System.out.println("服务端停止发送数据给<>");

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

客户端

SocketClientA 多个客户端可以将此类复制多个

public class SocketClientA {

static Socket socket;

static BufferedReader br; //控制台输入

static BufferedReader in; //读取服务端信息输入流

static PrintWriter writer; //发送给服务端信息的输出流

class Accepter extends Thread{

@Override

public void run() {

int i= 1;

String readLine="";

try {

do{

readLine = in.readLine();

if(null != readLine){

System.out.println(readLine);

}

System.out.println("客户端第"+i+"次接收信息为:"+readLine);

i++;

}while(!"exit".equals(readLine));

//关闭socket输入流

//in.close(); 采用关闭流的方式会导致socket被关闭

socket.shutdownInput();

System.out.println("客户端停止接收数据");

} catch (IOException e) {

e.printStackTrace();

}

}

}

class Sender extends Thread{

@Override

public void run() {

int i= 1;

String readLine ="";

try {

do{

readLine = br.readLine();

if(null != readLine){

writer.println(readLine);

writer.flush();

System.out.println("客户端第"+i+"次发送信息为:"+readLine);

i++;

}

}while (!"exit".equals(readLine));

//当客户端输入exit后关闭socket输出流

br.close();

//writer.close(); 采用流的关闭方式会导致socket关闭

socket.shutdownOutput();

System.out.println("客户端停止发送数据");

} catch (IOException e) {

e.printStackTrace();

}

}

}

// 搭建客户端

public static void main(String[] args) throws IOException {

try {

// 1、创建客户端Socket,指定服务器地址和端口

socket = new Socket("127.0.0.1",5209);

System.out.println("客户端启动成功");

SocketClientA socketClient = new SocketClientA();

Sender sender = socketClient.new Sender();

Accepter accepter = socketClient.new Accepter();

br = new BufferedReader(new InputStreamReader(System.in));

in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

writer = new PrintWriter(socket.getOutputStream());

sender.start();

accepter.start();

} catch (Exception e) {

System.out.println("can not listen to:" + e);// 出错,打印出错信息

}

}

}

运行结果和分析

服务端控制台输出为

******服务器已启动,等待客户端连接*****

开启第1个socket

开启第2个socket

服务端第1次接收到来自<>信息为:111111

服务端第1次接收到来自<>信息为:222222

333333

服务端第1次发送信息给<>,信息为:333333

444444

服务端第1次发送信息给<>,信息为:444444

exit

服务端第2次发送信息给<>,信息为:exit

服务端停止发送数据给<>

服务端第2次接收到来自<>信息为:exit

服务端已停止接收<>的数据

服务端第2次接收到来自<>信息为:exit

服务端已停止接收<>的数据

2.客户端A控制台输出为

客户端启动成功

111111

客户端第1次发送信息为:111111

客户端第1次接收信息为:333333

客户端第2次接收信息为:exit

客户端停止接收数据

exit

客户端第2次发送信息为:exit

客户端停止发送数据

3.客户端B控制台输出为

客户端启动成功

222222

客户端第1次发送信息为:222222

客户端第1次接收信息为:444444

exit

客户端第2次发送信息为:exit

客户端停止发送数据

客户端第2次接收信息为:exit

客户端停止接收数据

分析:由于服务端的控制台输入只有一个入口,多线程中如果服务端某个socket关闭了控制台的输入流,那有可能其他socket正在读取,这是会导致io异常,所以服务端的输入流没有关闭。

有时候会出现服务端需要输入多次才能发送到客户端的现象,这可能是因为多个socket同时需要输入导致的。

在输入之前socket已经确定,发送给哪个客户端已经确定。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值