1. socket介绍
socket编程是网络常用的编程,我们通过在网络中创建socket关键字来实现网络间的通信
2. 编码示例
服务端:
package cn.com.gs.demo;
import cn.com.gs.common.socket.BasicCommunicator;
import cn.com.gs.common.util.StringUtil;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author Administator
* @date 2021-10-19 13:52
* @Description
*/
public class SocketServerTest {
public static void main(String[] args) throws Exception {
// 1. 创建套接字,绑定端口并监听
ServerSocket server = new ServerSocket(9000);
// 2. 阻塞,直到有客户端连接
System.out.println("你不来,我不走,风里雨里一直等你...");
Socket socket = server.accept();
// 3. 接收客户端消息,并回复
BasicCommunicator communicator = new BasicCommunicator(socket);
// todo 整合实际业务,编写一个处理器,将请求转到实际业务层,并拿到业务层处理结果,响应给客户端
// 参考NetSeal AppServer 的 SocketListener和SocketConnectionHandler
byte[] recv = communicator.recv();
System.out.println("服务端接收到的信息:" + StringUtil.getString(recv));
String message = "Bye";
communicator.send(StringUtil.getBytes(message));
// 4. 关闭连接
socket.close();
}
}
客户端
package cn.com.gs.demo;
import cn.com.gs.common.socket.BasicCommunicator;
import cn.com.gs.common.util.StringUtil;
import java.net.Socket;
/**
* @author Administator
* @date 2021-10-19 13:52
* @Description
*/
public class SocketClientTest {
public static void main(String[] args) throws Exception {
// 1. 创建套接字,指定服务端Ip、Port
Socket socket = new Socket("127.0.0.1", 9000);
// 2. 向服务端发送消息,并等待回复
BasicCommunicator communicator = new BasicCommunicator(socket);
String message = "我是client";
communicator.send(StringUtil.getBytes(message));
byte[] recv = communicator.recv();
System.out.println(StringUtil.getString(recv));
socket.close();
}
}
公共收发类
package cn.com.gs.common.socket;
import cn.com.gs.common.define.Constants;
import cn.com.gs.common.util.HexUtil;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
/**
* @author Administator
* @date 2021-10-19 14:06
* @Description
*/
public class BasicCommunicator {
protected long maxRequestLength = Constants.LENGTH_5MB;
protected long maxResponseLength = Constants.LENGTH_5MB;
protected int READ_BLOCK_LENGTH = 1024; // 按块读
public Socket socket;
protected DataOutputStream out;
protected DataInputStream input;
/**
* 构造函数
*
* @param s
* 服务器与客户端的Socket连接
*/
public BasicCommunicator(Socket s) {
socket = s;
try {
out = new DataOutputStream(socket.getOutputStream());
input = new DataInputStream(socket.getInputStream());
} catch (Exception e) {
}
}
/**
* 发送二进制数据
*/
public void send(byte[] data) throws Exception {
byte[] bs = HexUtil.int2Byte(data.length);
byte[] sData = new byte[bs.length + data.length];
System.arraycopy(bs, 0, sData, 0, bs.length);
System.arraycopy(data, 0, sData, bs.length, data.length);
out.write(sData);
out.flush();
}
/**
* 读取数据开头4个字节,取得接受数据的长度.
*
* @return 数据长度
* @throws IOException
*/
public int recvLength() throws Exception {
int len = input.readInt();
if ((len <= 0) || (len > maxRequestLength))
throw new Exception("recv length is over limit, len is " + len);
return len;
}
public byte[] recv() throws Exception {
// 收到的报文长度
int len = recvLength();
byte[] allData = new byte[len];
byte[] data = null;
int rlen = len;
while (rlen > 0) {
if (rlen > READ_BLOCK_LENGTH)
data = new byte[READ_BLOCK_LENGTH];
else
data = new byte[rlen];
int alen = input.read(data);
System.arraycopy(data, 0, allData, len - rlen, alen);
rlen -= alen;
}
return allData;
}
public void close() {
try {
if (socket != null) {
socket.close();
}
} catch (Exception e) {
}
}
}