一个简单的自定义通信协议(socket)

来源:互联网 发布:房屋设计三维渲染软件 编辑:程序博客网 时间:2024/05/16 10:59

一直不知道socket通信时候自定义数据包是什么样子的,偶然做了个小例子。

 

先来说说数据包的定义,我这里是包头+内容 组成的:其中包头内容分为包类型+包长度, 那就是 消息对象=包类型+包长度+消息体

 

包类型 byte 型

包长度 int 型

消息体 byte[]

 

包总长度为 1 + 4 +  消息体.getBytes().length

 

发包方法如下:

Java代码  收藏代码
  1. private void sendTextMsg(DataOutputStream out,String msg ) throws IOException {  
  2.         byte[] bytes= msg.getBytes();  
  3.         int totalLen = 1 + 4 + bytes.length;  
  4.                                 out.writeByte(1);  
  5.         out.writeInt(totalLen);  
  6.         out.write(bytes);  
  7.         out.flush();  
  8.     }  

 

 

客户端发送消息类为:

 

Java代码  收藏代码
  1. import java.io.DataOutputStream;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.io.OutputStream;  
  5. import java.net.Socket;  
  6. import java.net.UnknownHostException;  
  7. import java.util.Scanner;  
  8.   
  9. public class MsgClient {  
  10.   
  11.     private DataOutputStream outs;  
  12.       
  13.     public static void main(String[] args) {  
  14.         try {  
  15.             MsgClient client = new MsgClient();  
  16.             client.connServer("127.0.0.1"9292);             
  17.         } catch (UnknownHostException e) {  
  18.             e.printStackTrace();  
  19.         } catch (IOException e) {  
  20.             e.printStackTrace();  
  21.         }  
  22.     }  
  23.       
  24.       
  25.     private void sendTextMsg(DataOutputStream out,String msg ) throws IOException {  
  26.         byte[] bytes= msg.getBytes();  
  27.         int totalLen = 1 + 4 + bytes.length;  
  28.         out.writeByte(1);  
  29.         out.writeInt(totalLen);  
  30.         out.write(bytes);  
  31.         out.flush();  
  32.     }     
  33.       
  34.     public void connServer(String ip,int port) throws UnknownHostException, IOException {  
  35.         Socket client = new Socket(ip,port);  
  36.         InputStream in = client.getInputStream();  
  37.         OutputStream out = client.getOutputStream();  
  38.         outs = new DataOutputStream(out);  
  39.         while(true) {  
  40.             Scanner scaner = new Scanner(System.in);  
  41.             sendTextMsg(outs, "测试消");  
  42.         }         
  43.     }  

 

 

服务端接收类为:

 

Java代码  收藏代码
  1. import java.io.DataInputStream;  
  2. import java.io.FileOutputStream;  
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.net.ServerSocket;  
  6. import java.net.Socket;  
  7.   
  8. public class MsgServer {  
  9.     public static void main(String[] args) {          
  10.         try {  
  11.             MsgServer server = new MsgServer();  
  12.             server.setUpServer(9090);  
  13.         } catch (IOException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.     }  
  17.       
  18.     public void setUpServer(int port) throws IOException {  
  19.         ServerSocket server = new ServerSocket(port);  
  20.         while(true) {  
  21.             Socket client = server.accept();  
  22.             System.out.println("客户端IP:"+client.getRemoteSocketAddress());  
  23.             processMesage(client);  
  24.         }  
  25.     }  
  26.       
  27.     private void processMesage(Socket client) throws IOException {  
  28.         InputStream ins = client.getInputStream();        
  29.         DataInputStream dins = new DataInputStream(ins);  
  30.         //服务端解包过程  
  31.         while(true) {  
  32.             int totalLen = dins.readInt();  
  33.             byte flag = dins.readByte();  
  34.             System.out.println("接收消息类型"+flag);  
  35.               
  36.             byte[] data = new byte[totalLen - 4 - 1];  
  37.             dins.readFully(data);  
  38.             String msg = new String(data);  
  39.             System.out.println("发来的内容是:"+msg);    
  40.         }  
  41.     }  
  42. }  

 

 

 

这样就基本完成了,但实际还有好多问题,比如说服务端用如何用多线程服务来完成客户端的请求已提高效率,如果是NIO方式怎么来实现?多个消息类型时候怎么抽象?这些都没有考虑

 

另外有两个开源的框架不错,一个是apache  mina 还有个是netty ,有机会试试。

原创粉丝点击