`
vtrtbb
  • 浏览: 361585 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

    博客分类:
  • java
阅读更多

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

 

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

 

包类型 byte 型

包长度 int 型

消息体 byte[]

 

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

 

发包方法如下:

private void sendTextMsg(DataOutputStream out,String msg ) throws IOException {
		byte[] bytes= msg.getBytes();
		int totalLen = 1 + 4 + bytes.length;
                                out.writeByte(1);
		out.writeInt(totalLen);
		out.write(bytes);
		out.flush();
	}

 

 

客户端发送消息类为:

 

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class MsgClient {

	private DataOutputStream outs;
	
	public static void main(String[] args) {
		try {
			MsgClient client = new MsgClient();
			client.connServer("127.0.0.1", 9292);			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	private void sendTextMsg(DataOutputStream out,String msg ) throws IOException {
		byte[] bytes= msg.getBytes();
		int totalLen = 1 + 4 + bytes.length;
        out.writeByte(1);
		out.writeInt(totalLen);
		out.write(bytes);
		out.flush();
	}	
	
	public void connServer(String ip,int port) throws UnknownHostException, IOException {
		Socket client = new Socket(ip,port);
		InputStream in = client.getInputStream();
		OutputStream out = client.getOutputStream();
		outs = new DataOutputStream(out);
		while(true) {
			Scanner scaner = new Scanner(System.in);
			sendTextMsg(outs, "测试消");
		}		
	}

 

 

服务端接收类为:

 

import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MsgServer {
	public static void main(String[] args) {		
		try {
			MsgServer server = new MsgServer();
			server.setUpServer(9090);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void setUpServer(int port) throws IOException {
		ServerSocket server = new ServerSocket(port);
		while(true) {
			Socket client = server.accept();
			System.out.println("客户端IP:"+client.getRemoteSocketAddress());
			processMesage(client);
		}
	}
	
	private void processMesage(Socket client) throws IOException {
		InputStream ins = client.getInputStream();		
		DataInputStream dins = new DataInputStream(ins);
		//服务端解包过程
		while(true) {
			int totalLen = dins.readInt();
			byte flag = dins.readByte();
			System.out.println("接收消息类型"+flag);
			
			byte[] data = new byte[totalLen - 4 - 1];
			dins.readFully(data);
			String msg = new String(data);
			System.out.println("发来的内容是:"+msg);	
		}
	}
}

 

 

 

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

 

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

 

 

 

 

 

 

 

分享到:
评论
Global site tag (gtag.js) - Google Analytics