Java Socket 通信

Java Socket通信

问题描述

服务器端同时接收多个客户端的数据,对这些数据进行处理后,在返回给对应的客户端。

解决思路

  1. 服务器监听客户端的连接;
  2. 服务器接收多个客户端发来的数据,并将socket保存;
  3. 进行数据处理;
  4. 将处理后的结果返回给对应的客户端。

例子

一台服务器(IP,Port),三台客户端,每台客户端发送一个整型数组给服务器,服务器计算这些数组的差集(及每个数组去掉三个数组相同的元素),并将结果返回给对应的客户端。

代码实现

服务器端:

public class Server{
	public static Map<MyChannel,int[]> dataMap = new HashMap<MyChannel,int[]>();//存放管道和对应接收到的数据
	public static int clientNum = 3;//指定客户端的数量
	private int serverPort = 8888;
	
	public void start() throws IOException{
		ServerSocket server = new ServerSocket(serverPort);
		while(true){
			Socket socket = server.accept();
			new Thread(new MyChannel(socket)).start(); 
		}
	}
	
	public static void main(String[] args){
		Server server = new Server();
		try{
			server.start();
			Thread.sleep(2000);//保证将所有的数据都存入到了dataMap中
		}catch(IOException e){
			e.printStackTrace();
		}catch(InterruptedException e){
			e.printStackTrace();
		}
		
		/*求差集,具体代码略去了*/
		//返回给客户端
		Set<MyChannel> myChannels = dataMap.keySet();
		for(MyChannel myChannel:myChannels){
			myChannel.send(dataMap.get(myChannel));
		}
	}
}

MyChannel类的代码:

/**
*1.MyChannel类保存了客户端到服务器的连接管道
*2.receive()方法放在线程中执行
*3.send(int[])方法在Server类中执行
**/
public class MyChannel implements Runnable{
	private ObjectInputStream ois;
	private ObjectOutputStream oos;
	
	public MyChannel(Socket socket){
		try{
			ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
			oos = new ObjectOutputStream(socket.getOutputStream());
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	public void send(int[] data){//将结果写出
		try{
			oos.writeObject(data);
			oos.flush();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	public void receive(){
		try{
			int[] recData = (int[]) ois.readObject();
			synchronized(Server.dataMap){//线程同步
				Server.dataMap.put(this,recData);
				if(Server.dataMap.size()<Server.cientNum){
					try{
						Server.dataMap.wait();
					}catch(InterruptedException e){
						e.printStackTrace();
					}
				}else{
					Server.dataMap.notifyAll();
				}
			}
		}catch(IOException | ClassNotFoundException e){
			e.printStackTrace();
		}
	}
	
	@override
	public void run(){
		receive();//接收数据的时候需放在不同线程中
	}
}

客户端代码:

public class Client{
	static String serverIP = "IP of Server";
	static int serverPort = "8888";
	ObjectOutputStream oos;
	ObjectInputStream ois;
	public static void main(String[] args){
		int[] intArr = new int[]{1,2,3,4,5,6,7};
		Socket client = new Socket(serverIP,serverPort);
		oos = new ObjectOutputStream(client.getOutputStream());
		ois = new ObjcetInputStream(new BufferedInputStream(client.getInputStream()));
		//向服务器端发送数据
		oos.writeObject(intArr);
		oos.flush();
		//接收数据
		int[] newArr = ois.readObject();
		System.out.println(Arrays.toString(newArr));
	} 
}

小结

1.当在服务器端接收完数据后,将输入流关闭,处理完数据后发送数据时,会报错:socket is closed。
原因:当关闭输入流时,socket也随之关闭,因此无法在发送数据。
解决方法:应该在发送完数据后,统一关闭输入流和输出流以及socket
2.对象流循环读取数据时,判断读取到末尾的方法:
①利用异常捕获:当捕获到异常EOFException时,说明已经读到末尾了
②在传输数据的时候,可以在数据末尾追加一个null,当读取的值为null,则表示已经读到末尾了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值