⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.c

📁 非常好用的tcp/udp封装
💻 C
字号:
#include "tcp.h"int SockInit(void){#ifdef WIN32	WSADATA wsaData;	WORD version = MAKEWORD(2, 2);	int ret = WSAStartup(version, &wsaData);	if ( ret ) 	{		printf("Initilize winsock error !");		exit(-1);	}#endif	return 0;}int SockClean(void){#ifdef WIN32	return (WSACleanup());#else	return 0;	#endif}/////////////////////////////////////////////  TCP Server fucntion/////////////////////////////////////////////创建tcp服务器,成功返回1int CreateTcpServer(struct TcpServer *ser, unsigned short localport){	const int on = 1;	ser->sockfd = socket(AF_INET, SOCK_STREAM, 0);	if(ser->sockfd == INVALID_SOCKET)		return 0;		ser->localaddr.sin_family 	    = AF_INET;	ser->localaddr.sin_port 	    = localport;	ser->localaddr.sin_addr.s_addr  = htonl(INADDR_ANY);	if(bind(ser->sockfd, (struct sockaddr *)&ser->localaddr, sizeof(struct sockaddr_in))==SOCKET_ERROR)	{		closesocket(ser->sockfd);		return 0;	}		ioctl(ser->sockfd, FIONBIO, (unsigned long *)&on);	setsockopt(ser->sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on));		if(listen(ser->sockfd, LISTEN_NUM) == SOCKET_ERROR)	{		closesocket(ser->sockfd);		return 0;	}		signal(SIGPIPE, SIG_IGN);	ser->session = NULL;	return 1;}struct AcceptSession *AcceptConnect(struct TcpServer *ser, int timeout){	struct timeval tv;	struct timeval end;	SOCKET sock;	struct AcceptSession *sess;//	int on = 1;	socklen_t addr_len = sizeof(ser->remoteaddr);		tv.tv_sec = timeout;	tv.tv_usec = 0;		end.tv_sec = 15;	end.tv_usec = 0;		FD_ZERO(&ser->fdset);	FD_SET(ser->sockfd, &ser->fdset);		if(select(ser->sockfd+1, &ser->fdset, NULL, NULL, &tv) > 0)	{		sock = accept(ser->sockfd, (struct sockaddr*)&ser->remoteaddr, &addr_len);		if(sock == SOCKET_ERROR)			return NULL;		sess = (struct AcceptSession*)malloc(sizeof(struct AcceptSession));		if(sess == NULL)		{			closesocket(sock);			return NULL;		}	 		sess->sockfd = sock;		memcpy(&sess->remoteaddr, &ser->remoteaddr, sizeof(ser->remoteaddr));		sess->next = NULL;				setsockopt(sess->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&end, sizeof(end));		setsockopt(sess->sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&end, sizeof(end));				return sess;	}	return NULL;}//超时返回-1, 正常发送返回0,接收长度从recvlen返回int RecvFromSession(struct AcceptSession *session, char *buff, int *recvlen, int timeout){	struct timeval tv;	tv.tv_sec = timeout;	tv.tv_usec = 0;		FD_ZERO(&session->fdset);	FD_SET(session->sockfd, &session->fdset);		if(select(session->sockfd+1, &session->fdset, NULL, NULL, &tv)>0)	{		if(FD_ISSET(session->sockfd, &session->fdset) > 0)		{			*recvlen = recv(session->sockfd, buff, 4096, 0);		}	}	else return -1;	return 0;}//成功返回发送的长度,否则返回-1int SendToSession(struct AcceptSession *session, char *buff, int len, int timeout){	struct timeval tv;	tv.tv_sec = timeout;	tv.tv_usec = 0;		FD_ZERO(&session->fdset);	FD_SET(session->sockfd, &session->fdset);		if(select(session->sockfd+1, NULL, &session->fdset, NULL, &tv) > 0)	{		if(FD_ISSET(session->sockfd, &session->fdset) > 0)		{			return send(session->sockfd, buff, len, 0);		}	}	return -1;	}int DeleteTcpSession(struct AcceptSession *session){	if(session->sockfd > 0)	{		shutdown(session->sockfd, SD_BOTH);		close(session->sockfd);	}	free((void*)session);	return 1;	}//////////////////////////////////////////////  TCP Client fucntion//////////////////////////////////////////////创建成功,返回1,否则返回0		int CreateTcpClient(struct TcpClient *client, unsigned int serip, unsigned short serport, int timeout){	SOCKADDR_IN  server;	struct timeval tv;	int on = 1;	struct timeval end;    end.tv_sec  = 15;    end.tv_usec = 0;		client->sockfd = socket(AF_INET, SOCK_STREAM, 0);	if(client->sockfd == SOCKET_ERROR) 		return 0;	client->connected = 0;				//连接服务器	tv.tv_sec = timeout;	tv.tv_usec = 0;	memset(&server, 0, sizeof(server));	server.sin_family       = AF_INET;	server.sin_port         = serport;	server.sin_addr.s_addr  = serip;		//连接前设置为非阻塞	signal(SIGPIPE, SIG_IGN);	ioctl(client->sockfd, FIONBIO, (unsigned long *)&on);		if(connect(client->sockfd, (struct sockaddr*)&server, sizeof(server)) == 0)	{//连接成功		on = 0;		ioctl(client->sockfd, FIONBIO, (unsigned long *)&on);						setsockopt(client->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&end, sizeof(end));		setsockopt(client->sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&end, sizeof(end));				client->connected = 1;		printf("------------------");		return 1;	}		FD_ZERO(&client->fdset);	FD_SET(client->sockfd, &client->fdset);	//要检查读写	if(select(client->sockfd+1, &client->fdset, &client->fdset, NULL, &tv) > 0)	{		if(FD_ISSET(client->sockfd, &client->fdset))		{			on = 0;			ioctl(client->sockfd, FIONBIO, (unsigned long *)&on);				//	struct timeval end={15,0};			setsockopt(client->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&end, sizeof(end));			setsockopt(client->sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&end, sizeof(end));					client->connected = 1;			//printf("++++++++++++++++++++");			return 1;		}	}	return 0;	}int DeleteTcpClient(struct TcpClient *client){	if(client->sockfd > 0)	{		shutdown(client->sockfd, SD_BOTH);		close(client->sockfd);	}	return 1;				}//成功返回发送的长度,否则返回-1int SendToServer(struct TcpClient *client, char *buff, int len, int timeout){/*		struct timeval tv;	tv.tv_sec = timeout;	tv.tv_usec = 0;		FD_ZERO(&client->fdset);	FD_SET(client->sockfd, &client->fdset);	printf("will send\n");	if(select(client->sockfd, NULL, &client->fdset, NULL, &tv) > 0)	{		if(FD_ISSET(client->sockfd, &client->fdset))		{			return send(client->sockfd, buff, len, 0);			}	}	else {		printf("send timeout\n");			return -1;	}*///	return send(client->sockfd, buff, len, 0);	int ll = send(client->sockfd, buff, len, 0);	if(ll < 0 && errno == EPIPE)	{		printf("peer close\n");		return -1;	}	return ll;}//超时返回-1, 正常发送返回0int RecvFromServer(struct TcpClient *client, char *buff, int *recvlen, int timeout){	struct timeval tv;	tv.tv_sec = timeout;	tv.tv_usec = 0;		FD_ZERO(&client->fdset);	FD_SET(client->sockfd, &client->fdset);		if(select(client->sockfd, &client->fdset, NULL, NULL, &tv) > 0)	{		if(FD_ISSET(client->sockfd, &client->fdset))		{			*recvlen = recv(client->sockfd, buff, 4096, 0);		}	}	else return -1;	return 0;}/////////////////////////////////////////////  UDP Server fucntion///////////////////////////////////////////
int CreateUdpServer(struct UdpServer*  server, unsigned short serport){	const int on = 1;	int sndsize,rcvsize;	sndsize = 1024*16;    rcvsize = 1024*64;	server->sockfd = socket(AF_INET, SOCK_DGRAM, 0);	if(server->sockfd == INVALID_SOCKET)		return 0;	memset(&server->localaddr, 0, sizeof(SOCKADDR_IN));	server->localaddr.sin_family      = AF_INET;	server->localaddr.sin_port        = serport;	server->localaddr.sin_addr.s_addr = htonl(INADDR_ANY);	setsockopt(server->sockfd, SOL_SOCKET, SO_SNDBUF, &sndsize, sizeof(int));	setsockopt(server->sockfd, SOL_SOCKET, SO_RCVBUF, &rcvsize, sizeof(int));	setsockopt(server->sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));	if(bind(server->sockfd, (struct sockaddr*)&server->localaddr, sizeof(server->localaddr)) < 0)	{		printf("udp bind error\n");		return 0;	}		return 1;}//接收数据,内部缓冲为4096,成功返回数据长度int RecvFromClient(struct UdpServer*  server, char* buff){	int ret;	int len;	struct timeval	tv;	tv.tv_sec = 0;	tv.tv_usec = 0;	len = sizeof(server->remoteaddr);    FD_ZERO(&server->fdset);	FD_SET(server->sockfd, &server->fdset);    	ret = select(server->sockfd+1, &server->fdset, NULL, NULL, &tv);	if(ret <= 0) return 0;	if(FD_ISSET(server->sockfd, &server->fdset) > 0)	{		return recvfrom(server->sockfd, buff, 1024*15, 0,				(struct sockaddr *)&server->remoteaddr, &len);	}}int SendToClient(struct UdpServer* server, char* buff, int len){	return sendto(server->sockfd, buff, len, 0, (struct sockaddr*)&server->remoteaddr,					sizeof(server->remoteaddr));}/**************************************************	UDP	client**************************************************/int CreateUdpClient(struct UdpClient* client, unsigned int serip, unsigned short serport){	const int on = 1;	int sndsize,rcvsize;	sndsize = 1024*16;    rcvsize = 1024*64;	client->sockfd = socket(AF_INET, SOCK_DGRAM, 0);	if(client->sockfd == INVALID_SOCKET)		return 0;		//填写服务器端套接字	memset(&client->serveraddr, 0, sizeof(client->serveraddr));	client->serveraddr.sin_family       = AF_INET;	client->serveraddr.sin_port         = serport;	client->serveraddr.sin_addr.s_addr  = serip;		//设置套接字属性	setsockopt(client->sockfd, SOL_SOCKET, SO_SNDBUF, &sndsize, sizeof(int));	setsockopt(client->sockfd, SOL_SOCKET, SO_RCVBUF, &rcvsize, sizeof(int));	setsockopt(client->sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));	return 1;}//接收数据,内部缓冲为4096,成功返回数据长度int RecvFromUdpServer(struct UdpClient*  client, char* buff){	int ret;	int len;	struct timeval	tv;	tv.tv_sec = 0;	tv.tv_usec = 0;	len = sizeof(client->remoteaddr);	ret = select(client->sockfd+1, &client->fdset, NULL, NULL, &tv);	if(ret <= 0) return 0;	if(FD_ISSET(client->sockfd, &client->fdset) > 0)	{		return recvfrom(client->sockfd, buff, 4096, 0,\				(struct sockaddr *)&client->remoteaddr, &len);	}	return 0;}int SendToUdpServer(struct UdpClient* client, char* buff, int len){	return sendto(client->sockfd, buff, len, 0, (struct sockaddr*)&client->serveraddr,\					sizeof(client->serveraddr));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -