📄 tcplib.c
字号:
/*************************************************************************** Copyright : 2002, ASPIRE TECHNOLOGIES (SHENZHEN) LTD. Program ID : tcplib.c Description : socket 实现简单源文件 Version : cmppapi 1.5 Modification Log: DATE AUTHOR DESCRIPTION -------------------------------------------------------------------------- 2002-11-25 wenyz Create***************************************************************************/#include "tcplib.h"#include "log.h"/************************************************************************** Function Name Description: this function will construct a tcp connection to destinated server Parameters: char* sHost(I) - the hostname or IP address of server to be connected int nServ(I) - the service name or port number Return Value: int >0 success TCPLIB_FAIL error Return Value : *************************************************************************/int nTcpConnect_Api( const char* sHost, int nServ ){ int nSockfd; int nRetConn; struct sockaddr_in rServaddr; struct linger rLinger; int nRetSetOpt; memset(&rServaddr, 0, sizeof(rServaddr)); rServaddr.sin_family = AF_INET; rServaddr.sin_port = htons((unsigned short)nServ); rServaddr.sin_addr.s_addr = inet_addr(sHost); nSockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if( nSockfd < 0) { return TCPLIB_FAIL; } rLinger.l_onoff = 1; // 打开linegr开关 rLinger.l_linger = 0; // 设置延迟时间为 0 秒, 注意 TCPIP立即关闭,但是有可能出现化身 if( (nRetSetOpt = setsockopt(nSockfd, SOL_SOCKET, SO_LINGER, (char *)&rLinger, sizeof(rLinger))) != 0 ) { nTcpClose_Api(nSockfd); return TCPLIB_FAIL; } if(0 > (nRetConn = connect(nSockfd, (struct sockaddr*)&rServaddr, sizeof(rServaddr)))) { nTcpClose_Api(nSockfd); return TCPLIB_FAIL; } return nSockfd;} /************************************************************************** Function Name Description : the call of this function will construct a tcp server on desig nated IP and PORT Parameters : const char* sHost(I) - the IP address or hostname of server if NULL,the IP address decided by system int nServ(I) - the port on which server will listen Return Value : int TCPLIB_OK success TCPLIB_FAIL error *************************************************************************/int nTcpListen_Api(const char* sHost, int nServ){ int nSockfd; int nRetSetOpt; int nRetBnd; int nOne; struct sockaddr_in rServaddr; struct linger rLinger; memset(&rServaddr, 0, sizeof(rServaddr)); rServaddr.sin_family = AF_INET; rServaddr.sin_port = htons((unsigned short)nServ); if(sHost == NULL) { rServaddr.sin_addr.s_addr = htonl(INADDR_ANY); } else { rServaddr.sin_addr.s_addr = inet_addr(sHost); } if( (nSockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0 ) { return TCPLIB_FAIL; } nOne = 1; if( (nRetSetOpt = setsockopt(nSockfd, SOL_SOCKET, SO_REUSEADDR,(char *)&nOne, sizeof(nOne))) != 0 ) { nTcpClose_Api(nSockfd); return TCPLIB_FAIL; } rLinger.l_onoff = 1; // 打开linegr开关 rLinger.l_linger = 0; // 设置延迟时间为 0 秒, 注意 TCPIP立即关闭,但是有可能出现化身 if( (nRetSetOpt = setsockopt(nSockfd, SOL_SOCKET, SO_LINGER, (char *)&rLinger, sizeof(rLinger))) != 0 ) { nTcpClose_Api(nSockfd); return TCPLIB_FAIL; } if( (nRetBnd = bind(nSockfd, (struct sockaddr*)&rServaddr, sizeof(rServaddr))) < 0 ) { nTcpClose_Api(nSockfd); return TCPLIB_FAIL; } if( listen(nSockfd, MacListenQueue) < 0 ) { nTcpClose_Api(nSockfd); return TCPLIB_FAIL; } return nSockfd;}/************************************************************************** Function Name Description : this function will block until a client construct a connetion to the server and the function will return a socket file descriptor representing the construted connnection Parameters : int nListenfd(I) - the socket descriptor returned by nTcpListen char* sIPClient(O) - the IP address of client who constructed the connection Return Value : int > 0 success TCPLIB_FAIL error Return Value : *************************************************************************//*int nTcpAccept(int nListenfd, char* sIPClient){ int nSockfd; int nLenCliAddr; struct sockaddr_in rCliAddr; nLenCliAddr = sizeof(rCliAddr); memset(&rCliAddr, 0, sizeof(rCliAddr)); for(;;) { nSockfd = accept(nListenfd, (struct sockaddr*)&rCliAddr, &nLenCliAddr); if( nSockfd < 0 ) { if( EINTR == errno || ENOBUFS == errno ) continue; else return TCPLIB_FAIL; } break; } if(sIPClient != NULL) { strcpy(sIPClient, (const char*)inet_ntoa(rCliAddr.sin_addr)); } return nSockfd;} *//************************************************************************** Function Name Description : this function will read n bytes from designated socket descriptor or return less than n bytes when timeout Parameters : int nSockfd(I) - socket fd from which data will be read the fd will be returned by nTcpConnect and nTcpAccept void* pvRecvBuf(IO) - the buf to receive data size_t nBytesToRead(I) - how many bytes the caller want to read int nTimeout(IO) - the timeout time ,unit is second,if NULL, will block...,if *pnTimeout == -1,time out Return Value : int > 0 - the bytes read = 0 - socket fd is nTcpClosed < 0 - error occured Return Value : *************************************************************************/ int nTcpReadn_Api(int nSockfd, char* pvRecvBuf, size_t nBytesToRead, int nTimeout){ int nLeft; int nRead; int nRet; int nRetSel; char* pvTmp; pvTmp = pvRecvBuf; nLeft = nBytesToRead; nRet = nBytesToRead; while( nLeft > 0 ) { nRetSel = nTcpSelect_Api(nSockfd, nTimeout); if(nRetSel == 0) { nRet = 0; break; } if(nRetSel <0) { nRet = -1; break; }#ifdef WIN32 if((nRead = recv(nSockfd, pvTmp, nLeft,0)) <= 0) { nRet = -2; break; }#else ifdef LINUX if((nRead = read(nSockfd, pvTmp, nLeft)) < 0) { if( errno == EINTR) { nRead = 0; } else { nRet = -2; break; } } if(nRead == 0) { nRet = 0; break; }#endif nLeft-=nRead; pvTmp+=nRead; } return nRet;}/************************************************************************** Function Name Description : this function will write n bytes data to designates socket fd Parameters : int nSockfd(I) - socket fd to write data to const void* pvSendBuf(I) - the buffer which contain the data to write size_t nBytesToWrite(I) - how many bytes to write Return Value : int > 0 - bytes that have been written -1 - error occured Parameters : Return Value : *************************************************************************/int nTcpWriten_Api(int nSockfd, const char* pvSendBuf, size_t nBytesToWrite){ int nLeft; int nWritten; const char* pcPtr; pcPtr = pvSendBuf; nLeft = nBytesToWrite;#ifdef WIN32 while( nLeft > 0 ) { if( 0 >= (nWritten = send(nSockfd, pcPtr, nLeft,0)) ) { return -1; } nLeft-=nWritten; pcPtr+=nWritten; }#else while( nLeft > 0 ) { if( 0 >= (nWritten = write(nSockfd, pcPtr, nLeft)) ) { if( EINTR == errno ) nWritten = 0; else return -1; } nLeft-=nWritten; pcPtr+=nWritten; }#endif return nBytesToWrite;}int nTcpSelect_Api(int nSockfd, int nTimeout){ int nRet; fd_set fds; struct timeval timeout; struct timeval *prTimeout; prTimeout = &timeout; FD_ZERO(&fds); FD_SET((unsigned int)nSockfd, &fds); if ( nTimeout <= 0 ) { prTimeout = NULL; } else { prTimeout->tv_sec = nTimeout; prTimeout->tv_usec = 0; } nRet =select(nSockfd+1, &fds, NULL, NULL, prTimeout); return nRet;}int nTcpClose_Api( int nSockfd ){#ifdef WIN32 return closesocket(nSockfd);#else return close(nSockfd);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -