- #pragma once
- #include <netinet/in.h>
- #include <unistd.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <netdb.h>
- #include <netinet/tcp.h>
- #include <sys/types.h>
- #include <linux/socket.h>
- #include "comhdr.h"
- #define CHECK_DWORD 0xaebecede
- #define INVALID_SOCKET (-1)
- #define SOCKET_ERROR (-1)
- //void sockInit();
- //void sockClean();
- BOOL sockCreateConnect(IN short nPort,OUT int *sock_srv); //服务端创建Socket
- BOOL sockWaitConnect(IN int sock_srv,OUT int *sock_con); //服务端等待连接(阻塞)
- BOOL sockToConnect(const char *szIp,short nPort,int *sock); //客户端去连接
- int sockRcvMsg(IN int sock,OUT char *buf,IN int bufLen); //只收一次数据
- int sockRcvMsgEx(IN int sock,OUT char *buf,IN int needLen); //收数据直至到needLen大小
- int sockSndMsg(IN int sock,IN char *buf,IN int bufLen); //发送数据
- void sockDestroy(IN int sock); //关闭socket
- //void sockInit()
- //{
- // WSADATA wsaData;
- // WSAStartup(MAKEWORD(2, 2), &wsaData);
- //}
- //void sockClean()
- //{
- // WSACleanup();
- //}
- void sockSetOption(int sock)
- {
- int iReuseAddr = SO_REUSEADDR;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&iReuseAddr, sizeof(iReuseAddr));
- //开启keepalive属性
- int keepAlive = 1;
- setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
- //连接在15秒内没有任何数据进行探测
- int keepIdle = 15;
- setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
- //探测发包时间间隔为5秒
- int keepInterval = 5;
- setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval)); // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
- //探测3次
- int keepCount = 3;
- setsockopt(sock, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
- }
- //服务端创建Socket
- BOOL sockCreateConnect(IN short nPort,OUT int *sock_srv)
- {
- int ret;
- sockaddr_in addrSrv;
- short ports = nPort;
- *sock_srv = socket(AF_INET, SOCK_STREAM, 0);
- if(*sock_srv == INVALID_SOCKET)
- {
- return FALSE;
- }
- addrSrv.sin_family = AF_INET;
- addrSrv.sin_addr.s_addr = htonl(INADDR_ANY);
- addrSrv.sin_port = htons(ports);
- ret = bind(*sock_srv,(sockaddr*)&addrSrv, sizeof(sockaddr));
- if(ret == SOCKET_ERROR)
- {
- close(*sock_srv);
- return FALSE;
- }
- ret = listen(*sock_srv, SOMAXCONN);
- if(ret == SOCKET_ERROR)
- {
- close(*sock_srv);
- return FALSE;
- }
- int iReuseAddr = SO_REUSEADDR;
- setsockopt(*sock_srv, SOL_SOCKET, SO_REUSEADDR, (void *)&iReuseAddr, sizeof(iReuseAddr));
- return TRUE;
- }
- //等待连接
- BOOL sockWaitConnect(IN int sock_srv,OUT int *sock_con)
- {
- socklen_t sockSize;
- sockaddr_in addrClient;
- int sock_client;
- sockSize = sizeof(sockaddr);
- sock_client = accept(sock_srv,(sockaddr*)&addrClient,&sockSize);
- int iReuseAddr = SO_REUSEADDR;
- setsockopt(sock_client, SOL_SOCKET, SO_REUSEADDR, (void *)&iReuseAddr, sizeof(iReuseAddr));
- sockSetOption(sock_client);
- /*
- DWORD chBuf;
- int ret = recv(sock_client, (char *)(&chBuf),sizeof(chBuf),0);
- if (ret == SOCKET_ERROR)
- {
- close(sock_client);
- //printf("sockCreateConnect : recv socket failed,error id : %u.\\n",WSAGetLastError());
- return FALSE;
- }
- if (CHECK_DWORD != chBuf)
- {
- //printf("sockCreateConnect : not my care.\\n");
- close(sock_client);
- return FALSE;
- }
- */
- *sock_con = sock_client;
- return TRUE;
- }
- //客户端连接
- BOOL sockToConnect(IN const CHAR* szIp,IN short nPort,OUT int *sock)
- {
- sockaddr_in addrSrv;
- const CHAR* ip = szIp;
- do
- {
- int ret;
- *sock = socket(AF_INET, SOCK_STREAM, 0);
- if (INVALID_SOCKET == *sock)
- {
- //printf("sockToConnect : socket create failed\\n");
- break;
- }
- if (szIp == NULL)
- {
- ip = "127.0.0.1";
- }
- addrSrv.sin_addr.s_addr = inet_addr(ip);
- addrSrv.sin_family = AF_INET;
- addrSrv.sin_port = htons(nPort);
- ret = connect(*sock, (sockaddr*)&addrSrv, sizeof(sockaddr));
- if (ret == SOCKET_ERROR)
- {
- //printf("sockToConnect : socket connect failed\\n");
- break;
- }
- sockSetOption(*sock);
- /*
- DWORD inBuf = CHECK_DWORD;
- ret = send(*sock, (char *)&inBuf, sizeof(DWORD), 0);
- if (ret == SOCKET_ERROR)
- {
- //printf("sockToConnect : socket send failed\\n");
- break;
- }
- */
- return TRUE;
- } while (0);
- if(INVALID_SOCKET != *sock)
- {
- close(*sock);
- *sock = INVALID_SOCKET;
- }
- return FALSE;
- }
- //收到一次就返回
- int sockRcvMsg(IN int sock,OUT char *buf,IN int bufLen)
- {
- int iRet = recv(sock, (CHAR *)buf, bufLen, MSG_NOSIGNAL);
- if(iRet == 0 && errno != 0 && errno != EAGAIN)
- {
- iRet = SOCKET_ERROR;
- }
- return iRet;
- }
- //会等到收到needLen了以后才返回
- int sockRcvMsgEx(IN int sock,IN char *data,IN int datalen)
- {
- int iRet;
- int iReaded = 0;
- fd_set rfd;
- for(;;)
- {
- iRet = recv(sock,(char *)data+iReaded,datalen-iReaded,MSG_NOSIGNAL);
- if (iRet == -1)
- {
- if(errno == EAGAIN)
- {
- FD_ZERO(&rfd);
- FD_SET(sock,&rfd);
- iRet = select(sock+1, &rfd, NULL, NULL, NULL);
- if (FD_ISSET(sock,&rfd) && iRet > 0)
- {
- continue;
- }
- else if (iRet == 0)
- {
- if (errno == 0)
- {
- continue;
- }
- else if (errno == EAGAIN)
- {
- continue;
- }
- else
- {
- iRet = SOCKET_ERROR;
- break;
- }
- }
- else if (iRet == -1)
- {
- iRet = SOCKET_ERROR;
- break;
- }
- }
- else
- {
- iRet = SOCKET_ERROR;
- break;
- }
- }
- else if(iRet == 0)
- {
- iRet = SOCKET_ERROR;
- break;
- }
- else
- {
- iReaded += iRet;
- if (iReaded == datalen)
- {
- iRet = iReaded;
- break;
- }
- }
- }
- return iRet;
- }
- //发送数据
- int sockSndMsg(IN int sock,IN char *buf,IN int bufLen)
- {
- int iRet = send(sock,(char *)buf,bufLen,MSG_NOSIGNAL);
- if(iRet == 0 && errno != 0 && errno != EAGAIN)
- {
- iRet = SOCKET_ERROR;
- }
- return iRet;
- }
- //发送datelen大小的数据
- int sockSndMsgEx(IN int sock,IN char *data,IN int datalen)
- {
- int iRet;
- int iWrited = 0;
- fd_set wfd;
- for(;;)
- {
- iRet = send(sock,(char *)data+iWrited,datalen-iWrited,MSG_NOSIGNAL);
- if (iRet == -1)
- {
- if(errno == EAGAIN)
- {
- FD_ZERO(&wfd);
- FD_SET(sock,&wfd);
- iRet = select(sock+1, NULL, &wfd, NULL, NULL);
- if (FD_ISSET(sock,&wfd) && iRet > 0)
- {
- continue;
- }
- else if (iRet == 0)
- {
- if (errno == 0)
- {
- continue;
- }
- else if (errno == EAGAIN)
- {
- continue;
- }
- else
- {
- iRet = SOCKET_ERROR;
- break;
- }
- }
- else if (iRet == -1)
- {
- iRet = SOCKET_ERROR;
- break;
- }
- }
- else
- {
- iRet = SOCKET_ERROR;
- break;
- }
- }
- else if(iRet == 0)
- {
- iRet = SOCKET_ERROR;
- break;
- }
- else
- {
- iWrited += iRet;
- if (iWrited == datalen)
- {
- iRet = iWrited;
- break;
- }
- }
- }
- return iRet;
- }
- //接收数据
- void sockDestroy(IN int sock)
- {
- shutdown(sock,2);
- close(sock);
- }
- //该片段来自于http://www.codesnippet.cn/detail/140620134023.html
来源: http://www.codesnippet.cn/detail/140620134023.html