java实现Socket通讯demo

Socket通讯

socket分为UDP和TCP两种协议
可以建立长连接socket和短链接socket 区别在于不关闭socket 多次发送和发送一次后关闭socket
UDP建立socket:

// 服务端
DatagramSocket ds = new DatagramSocket(9090);
// 客户端
byte[] data = new byte[10];
// 获取本机ip
InetAddress localHost = InetAddress.getLocalHost();
new DatagramPacket(data,0,data.length,localHost,9090);

TCP建立socket:

// 服务端
ServerSocket ss = new ServerSocket(9090);
// 客户端
Socket socket = new Socket("127.0.0.1",9090);

TCP 客户端Demo

public static void main(String[] args) {
	Socket s = null;
	String testData = "测试数据";
	try {
		s = new Socket("127.0.0.1",9090);
		OutputStream outputStream = s.getOutputStream();
		// 根据业务自定义编码
		outputStream.write(testData.getBytes("GBK"));
	
		InputStream inputStream = s.getInputStream();
		// 读取服务端响应
		String read = read(inputStream);
	
		log.info("客户端收到的数据:"+read);
	} catch (IOException e) {
		e.printStackTrace();
	}finally{
		if(null != outputStream){
			try{
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if(null != inputStream){
			try{
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if(null != s ){
			try {
				s.close();
			}catch (IOException e){
				e.printStackTrace();
			}
		}
	}
}

TCP 服务端Demo

public static void main(String[] args) {
	ServerSocket ss = null;
	try{
		ss = new ServerSocket(9090);
		while (true){
			// 阻塞等待客户端链接
			Socket accept = ss.accept();
			OutputStream os = null;
			InputStream is = null;
			try {
				os = accept.getOutputStream();
				is = accept.getInputStream();
				// 读取客户端的数据
				String message = read(is);
				String mes = "";
				if(null == message){
					mes = "数据接收失败";
					log.error("数据接收失败!");
				}else{
					// 业务逻辑
					mes = "业务处理完成";
				}
				// 响应给客户端的数据
				os.write(mes.getBytes("GBK"));
				accept.close();
			} catch (IOException | InterruptedException e) {
				e.printStackTrace();
				log.error("error:",e);
			}  finally {
				if(null != is){
					try {
						is.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(null != os){
					try {
						os.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}catch (IOException e){
		e.printStackTrace();
		log.error("error:",e);
	}finally {
		if(null != ss ){
			try {
				ss.close();
			}catch (IOException e){
				e.printStackTrace();
			}
		}
	}
}

读取数据

public static String read(InputStream inputStream) throws IOException{
		if(null == inputStream){return null;}
		String data = "";
		try{
			// 读取报文内容这里写死1024 正常传输数据会约定数据长度
			byte[] bys = new byte[1024];
			int len = inputStream.read(bys);
			data = new String(bys, "GBK");
		}catch (Exception e){
			e.printStackTrace();
			log.error("读取数据异常",e);
		}
		//输出数据
		return data;
	}

接收数据不全处理

public static synchronized String read(InputStream inputStream) throws IOException, InterruptedException {
		if(null == inputStream){return null;}
		int countRead = 0;
		int dataLengthByte = 8;
		// 获取前8位数据长度
		byte[] bys = new byte[dataLengthByte];
		int len;
		len = inputStream.read(bys);
		countRead +=len;
		String dataLength = new String(bys, "GBK");
		int i ;
		try{
			i = Integer.parseInt(dataLength.trim());
		}catch (NumberFormatException e){
			log.error("异常数据无法解析!略过:【"+dataLength+"】");
			return null;
		}
		log.info("数据长度:"+i);
		boolean successFlag = true;
		String data = "";
		try{
			if(i == 0){return null;}
			i -= dataLengthByte;
			if(i < 0){return null;}
			// 读取报文内容
			bys = new byte[i];
			len = inputStream.read(bys);
			countRead += len;
			data = new String(bys, "GBK");
			if(countRead != i+dataLengthByte ){
				log.error("数据接收不完整继续接收!");
				successFlag = false;
				// 数据接收不完整继续接收
				int initLoop = 0;
				int maxLoop = 10;
				while(initLoop < maxLoop){
					Thread.sleep(1000);
					len = inputStream.read(bys,countRead-dataLengthByte,i-(countRead-dataLengthByte));
					countRead += len;
					log.error("第"+(initLoop+1)+"次继续接收,接收长度:"+len+"数组长度:"+bys.length+" 报文内容长度:"+i);
					if(countRead == i+dataLengthByte){
						data = new String(bys, "GBK");
						successFlag = true;
						log.error("续接成功!");
						// 接收成功
						break;
					}
					initLoop ++;
				}
			}
		}catch (Exception e){
			e.printStackTrace();
			log.error("读取数据异常",e);
		}
		//输出数据
		return successFlag?dataLength.concat(data):null;
	}

踩过的坑

读取流内容 和写入流内容的方式有很多
比如 :DataOutputStream
DataOutputStream.writeUTF();方法写入的内容 接收也同样要使用DataInputStream的readUTF();
使用inputStream的read()方法是收不到数据的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值