C/C++封装socket通信类


不管是socket通信程序的客户端还是服务端,准备工作的代码又长又难看占地方,影响了主程序的结构,必须分离出来。

一、读取、写入数据

1、recvn函数

//从已经准备好的socket中读取数据。
//sockfd:已经准备好的socket连接。
//buffer:接收数据缓冲区的地址。
//n:本次接收数据的字节数。
//返回值:成功接收到n字节的数据后返回true,socket连接不可用返回false。
bool recvn(const int sockfd, char *buffer, const size_t n) {
   
	int remain, len, idx;
	remain = n;
	idx = 0;
	while (remain > 0) {
   
		if ((len = recv(sockfd, buffer + idx, remain,0)) <= 0)
			return false;
		idx += len;
		remain -= len;
	}
	return true;
}

2、sendn函数

//向已经准备好的socket中写入数据。
//sockfd:已经准备好的socket连接。
//buffer:待发送数据缓冲区的地址。
//n:待发送数据的字节数,缺省值是0时默认为buffer的大小。
//返回值:成功发送完n字节的数据后返回true,socket连接不可用返回false。
bool sendn(const int sockfd, const char *buffer, const size_t n = 0) {
   
	int remain, len, idx;
	remain = (n == 0) ? strlen(buffer) : n;
	idx = 0;
	while (remain > 0) {
   
		if ((len = send(sockfd,buffer + idx, remain,0)) <= 0)
			return false;
		idx += len;
		remain -= len;
	}
	return true;
}

3、TcpRecv函数

//接收socket的对端发送过来的数据。
//sockfd:可用的socket连接。
//buffer:接收数据缓冲区的地址。
//ibuflen:本次成功接收数据的字节数。解决TCP网络传输「粘包」
//itimeout:接收等待超时的时间,单位:秒,缺省值是0-无限等待。
//返回值:true-成功;false-失败,失败有两种情况:1)等待超时;2)socket连接已不可用。
bool TcpRecv(const int sockfd,char *buffer,int *ibuflen,const int itimeout = 0) {
   
	if (sockfd == -1) return false;
	if (itimeout > 0) {
     //延时操作 
		fd_set tmpfd;

		FD_ZERO(&tmpfd);
		FD_SET(sockfd,&tmpfd);

		struct timeval timeout;
		timeout.tv_sec = itimeout;
		timeout.tv_usec = 0;

		//如果在itimeout时间内没有可用资源的文件描述符的话就退出 
		if (select(sockfd+1,&tmpfd,0,0,&timeout) <= 0) return false;
	}

	//数据包 = 数据大小 + 数据
	(*ibuflen) = 0;

	if(!recvn(sockfd,(char*)ibuflen,4)) return false;

	(*ibuflen)=ntohl(*ibuflen);  //把网络字节序转换为主机字节序。
	
	return recvn(sockfd, buffer, *ibuflen);
}

4、TcpSend函数

//向socket的对端发送数据。
//sockfd:可用的socket连接。
//buffer:待发送数据缓冲区的地址。
//ibuflen:待发送数据的字节数,如果发送的是ascii字符串,ibuflen取0,如果是二进制流数据,ibuflen为二进制数据块的大小。
//itimeout:接收等待超时的时间,单位:秒,值是0-无限等待。
//返回值:true-成功;false-失败,如果失败,表示socket连接已不可用。
bool TcpSend(const int sockfd,const char *buffer,const int ibuflen = 0,const int itimeout = 5) {
   
	if (sockfd == -1 ) return false;
	if (itimeout > 0) {
     //延时操作 
		fd_set tmpfd;

		FD_ZERO(&tmpfd);
		FD_SET(sockfd,&tmpfd);

		struct timeval timeout;
		timeout.tv_sec = itimeout;
		timeout.tv_usec = 0;

		//如果在itimeout时间内没有可用资源的文件描述符的话就退出 
		if (select(sockfd+1,&tmpfd,0,0,&timeout) <= 0) return false;
	}

	//如果长度为0,就采用字符串的长度
	int ilen = (ibuflen == 0) ? strlen(buffer) : ibuflen;

	int ilenn=
  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值