WEB开发网
开发学院软件开发C++ 简单socket 阅读

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

点击下载此文件

Tags:简单 socket

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接