www.pudn.com > tcp-udp.rar > tcp.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服务器,成功返回1
int 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;
}
//成功返回发送的长度,否则返回-1
int 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;				
}

//成功返回发送的长度,否则返回-1
int 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, 正常发送返回0
int 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));
}