简单socket
2012-05-16 17:26:20 来源:WEB开发网核心提示:#pragma once#include <netinet/in.h>#include <unistd.h>#include <sys/socket.h>#include <arpa/inet.h>#include <stdio.h>#include <
#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);
}
赞助商链接

点击下载此文件