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));
}