《Linux内核视角:自定义协议与TCP的协同通信之道》
前引:在Linux占据核心地位的服务器与嵌入式领域,网络通信始终是技术架构的“主动脉”。TCP协议凭借其面向连接、可靠传输的特性,成为互联网通信的基石,但通用化的设计也使其在工业控制、金融交易、物联网等特定场景中,难以满足业务对协议轻量化、语义定制化的需求——这正是自定义协议的价值所在。自定义协议并非对TCP的替代,而是基于TCP字节流传输能力的“上层重构”,通过封装业务专属的指令、数据格式与交互逻辑,实现通信效率与业务适配性的双重提升。本文将从Linux网络栈工作机制出发,厘清自定义协议与TCP的协同关系,既剖析底层数据传输的原理,又结合实战案例讲解协议设计、TCP连接管理、数据编解码等核心环节,为开发者提供一套从理论到落地的完整解决方案!
【一】TCP协议-服务端
如果要自定义协议后续肯定需要TCP的客户端和服务端的通信,所以我们先完成TCP通信接口封装
(1)网络套接字
//网络套接字
int Socket()
{
socket_ = socket(AF_INET,SOCK_STREAM,0);
if(fd==-1)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"错误码:%d,错误信息:%s",errno,strerror(errno));
exit(LOG_LEVEL_SOCKET);
}
else
{
log_message(LOG_LEVEL_SUCCESS,__FILE__,__LINE__,"socket is successful");
}
return socket_;
}
(2)绑定IP和端口
//绑定IP和端口
void Bind()
{
struct sockaddr_in ser_addr;
memset(&ser_addr,0,sizeof(ser_addr));
ser_addr.sin_family=AF_INET;
ser_addr.sin_addr.s_addr=htonl(INADDR_ANY);
ser_addr.sin_port=htons(8080);
int bin =bind(socket_,(const sockaddr*)&ser_addr,sizeof(ser_addr));
if(bin==-1)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"错误码:%d,错误信息:%s",errno,strerror(errno));
exit(LOG_LEVEL_BIND);
}
else
{
log_message(LOG_LEVEL_SUCCESS,__FILE__,__LINE__,"bind is successful");
}
}
(3)监听
//监听
void Listen()
{
int lis =listen(socket_,max_listen);
if(lis==-1)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"错误码:%d,错误信息:%s",errno,strerror(errno));
exit(LOG_LEVEL_LISTEN);
}
else
{
log_message(LOG_LEVEL_SUCCESS,__FILE__,__LINE__,"listen is successful");
}
}
(4)接收客户端请求
//接收客户端请求
int Accept()
{
struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
socklen_t sz = sizeof(addr);
new_socket_ =accept(socket_,(sockaddr*)&addr,&sz);
if(new_socket_==-1)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"错误码:%d,错误信息:%s",errno,strerror(errno));
exit(LOG_LEVEL_ACCEPT);
}
else
{
log_message(LOG_LEVEL_SUCCESS,__FILE__,__LINE__,"accept is successful");
}
return new_socket_;
}
(5)读取客户端内容
//读取客户端内容
std::string Recv(const int& new_token)
{
char buf_ip[50]={0};
//inet_ntop(AF_INET,&(addr.sin_addr.s_addr),buf_ip,sizeof(buf_ip));
char buffer[max_buffer]={0};
size_t t =recv(new_token, buffer, sizeof(buffer)-1, 0);
if(t>0)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"Recv is successful");
}
else if(t==0)
{
std::cout<<"对方关闭了连接"<<buf_ip<<std::endl;
}
else
{
std::cout<<"服务端读取错误"<<std::endl;
}
return buffer;
}
【二】TCP协议-客户端
(1)网络套接字
//网络套接字
int Socket()
{
socket_ = socket(AF_INET,SOCK_STREAM,0);
if(socket_==-1)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"错误码:%d,错误信息:%s",errno,strerror(errno));
exit(LOG_LEVEL_SOCKET);
}
else
{
log_message(LOG_LEVEL_SUCCESS,__FILE__,__LINE__,"socket is successful");
}
return socket_;
}
(2)客户端发送请求
//客户端发送请求
void Connect()
{
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family=AF_INET;
inet_pton(AF_INET, "120.48.75.223", &addr.sin_addr.s_addr);
addr.sin_port=htons(atoi("8080"));
socklen_t ip_addr=sizeof(addr);
int can = connect(socket_,(const sockaddr*)&addr,ip_addr);
if(can==-1)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"错误码:%d,错误信息:%s",errno,strerror(errno));
exit(LOG_LEVEL_CONNECT);
}
}
(3)读取服务端内容
//读取服务端端内容
std::string Recv()
{
char buf_ip[50]={0};
//inet_ntop(AF_INET,&(addr.sin_addr.s_addr),buf_ip,sizeof(buf_ip));
char buffer[max_buffer]={0};
size_t t =recv(socket_, buffer, sizeof(buffer)-1, 0);
if(t>0)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"Recv is successful");
}
else if(t==0)
{
std::cout<<"对方关闭了连接"<<buf_ip<<std::endl;
}
else
{
std::cout<<"客户端读取错误"<<std::endl;
}
return buffer;
}
(4)发送给服务端
//发送给服务端
void Send(const std::string& se)
{
size_t sz = send(socket_,se.c_str(),se.size(),0);
if(sz>0)
{
log_message(LOG_LEVEL_ERROR,__FILE__,__LINE__,"Send is successful");
}
}



