📄 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服务器,成功返回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 + -