📄 serversock.c
字号:
#include "serversock.h"
#include "sockcomp.h"
//initiate the struct of ServerSockes and SocketsMsg
//use default value when user don't call this function
void InitServerSocks(ServerSockets *ssockets)
{
int i;
ssockets->DaemonSock = 0;
ssockets->DaemonPort = 0;
ssockets->RequestNum = 0;
ssockets->clientcount = 0;
ssockets->ReadNum = 0;
ssockets->WriteNum = 0;
ssockets->ExceptNum = 0;
for (i=0;i<64;i++)
{
ssockets->clientonline[i].ClientSock = 0;
//ssockets->clientonline[i].ClientPort = 1024;
strcpy(ssockets->clientonline[i].ClientIP,"000.000.000.000");
ssockets->ReadQueue[i] = 0;
ssockets->WriteQueue[i] = 0;
ssockets->ExceptQueue[i] = 0;
}
}
//监听套接口
MYBOOL mylisten(SOCKET s, int backlog)
{
int ret;
assert(s != 0);
ret = listen(s,backlog);
if (ret != 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("Listen() socket %d failed!\n", s);
#endif
return WRONG;
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("Listening socket %d\n", s);
#endif
}
return RIGHT;
}
//获取服务信息,用于只需要主动套接字的客户程序
//use to get ports and protocols of the system's net service
int InitSocketsStruct(char *servicename, char * protocol, ServerSockets *ssockets)
{
struct servent *servrec;
if ((servrec = getservbyname(servicename, protocol)) == NULL)
{
#if defined (SOCKCOMP_DEBUG)
printf("Get service %s and protocol %s failed!\n", servicename, protocol);
return(-1);
#endif
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("Get service %s and protocol %s successed!\n", servicename, protocol);
#endif
}
#if defined (LINUX)
bzero((char *)&ssockets, sizeof(ServerSockets));
#elif defined (WIN32)
memset(ssockets, 0, sizeof(ServerSockets));
#endif
ssockets->DaemonPort = servrec->s_port; // Service Port in Network Byte Order
return(1);
}
//Initialize Passive Socket. If succeed then return 1, else return error code (<0)
//获取服务信息并建立一个被动套接字,用于需要被动套接字的服务器程序
int InitPassiveSock(char * servicename, char * protocol, ServerSockets *ssockets)
{
SOCKET mainsock;
struct servent *servrec;
struct sockaddr_in serv_addr;
if ((servrec = getservbyname(servicename, protocol)) == NULL)
{
#if defined (SOCKCOMP_DEBUG)
printf("Get service %s and protocol %s failed!\n", servicename, protocol);
return(-1);
#endif
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("Get service %s and protocol %s successed!\n", servicename, protocol);
#endif
}
#if defined (LINUX)
bzero((char *)&ssockets, sizeof(ServerSockets));
#elif defined (WIN32)
memset(&ssockets, 0, sizeof(ServerSockets));
#endif
ssockets->DaemonPort = servrec->s_port; //Service Port in Network Byte Order
if((mainsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("Create the main sock in InitPassiveSock() failed!\n");
return(-1);
#endif
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("Create the main sock %d in InitPassiveSock() successed!\n", mainsock);
#endif
}
#if defined (LINUX)
bzero((char *)&serv_addr, sizeof(serv_addr));
#elif defined (WIN32)
memset(&serv_addr, 0, sizeof(serv_addr));
#endif
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //任意网络接口
serv_addr.sin_port = servrec->s_port;
if (bind(mainsock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
myclosesocket(mainsock);
return(-1);
}
//将主动套接字变为被动套接字,准备好接收连接
if (listen(mainsock, 5) == -1)
{
myclosesocket(mainsock);
return(-1);
}
if (!setsocketmode(mainsock, 1))
{
myclosesocket(mainsock);
return(-1);
}
ssockets->DaemonSock = mainsock;
FD_SET(mainsock, &(ssockets->readfds)); //申明对主套接字"可读"感兴趣
FD_SET(mainsock, &(ssockets->exceptfds)); //申明对主套接字上例外事件感兴趣
return(1);
}
//关闭主套接字,并清除对它上面事件的申明
void CloseMainSock(ServerSockets *ssockets)
{
myclosesocket(ssockets->DaemonSock);
FD_CLR(ssockets->DaemonSock, &(ssockets->readfds));
FD_CLR(ssockets->DaemonSock, &(ssockets->exceptfds));
}
//创建一个连接
int CreateConnection(struct in_addr *sin_addr, ServerSockets *ssocket)
{
#if defined (SOCKCOMP_DEBUG)
int tmp;
#endif
struct sockaddr_in server;
SOCKET tmpsock;
int i;
if ((tmpsock = mysocket(AF_INET, SOCK_STREAM, 0)) < 0)
{
return(-1);
}
server.sin_family = AF_INET;
server.sin_port = ssocket->DaemonPort;
server.sin_addr.s_addr = sin_addr->s_addr;
if(!setsocketmode(tmpsock, 1))
{
myclosesocket(tmpsock);
return(-2);
}
if (connect(tmpsock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
if ((errno != EWOULDBLOCK) && (errno != EINPROGRESS))
{
//如果错误代码是EWOULDBLOCK和EINPROGRESS,则不用关闭套接字,因为系统将在之后继续为套接字建立连接,连接是否建立成功可用select()函数来检测套接字是否"可写"来确定。*/
myclosesocket(tmpsock);
return(-3); //Connect error.
}
}
FD_SET(tmpsock, &(ssocket->readfds));
FD_SET(tmpsock, &(ssocket->writefds));
FD_SET(tmpsock, &(ssocket->exceptfds));
i = 0;
while (ssocket->clientonline[i].ClientSock != 0) i++; //look for a blank sockets position
if (i >= 64)
{
myclosesocket(tmpsock);
return(-4); //too many connections
}
ssocket->clientonline[i].ClientSock = tmpsock;
ssocket->clientcount++;
#if defined (SOCKCOMP_DEBUG)
tmp = ssocket->clientcount;
printf("The ssocket->clientcount is increase from %d to %d in CreateConnection().\n", tmp-1, tmp);
#endif
return(i);
}
void FilterDoubleClient(ServerSockets *ssocket, struct sockaddr_in * doubleaddr)
{
int i;
#if defined (SOCKCOMP_DEBUG)
int tmp, j;
#endif
for (i=0; i<ssocket->clientcount; i++)
{
if (!strcmp(ssocket->clientonline[i].ClientIP, inet_ntoa(doubleaddr->sin_addr)))
{
#if defined (SOCKCOMP_DEBUG)
printf("\n");
printf("Find a double address, now is in FilterDoubleClient(),\n");
#endif
CloseConnection(i, ssocket);
#if defined (SOCKCOMP_DEBUG)
tmp = ssocket->clientcount;
printf("The ssocket->clientcount is %d now,\n", tmp);
printf("This is the IP list now:\n");
for (j=0;j<ssocket->clientcount;j++)
{
printf("The IP of client %d is %s.\n", j, ssocket->clientonline[j].ClientIP);
}
printf("\n");
#endif
}
}
}
//接受客户端连接
int MyAccept(ServerSockets *ssocket)
{
#if defined (SOCKCOMP_DEBUG)
int tmp;
int j;
#endif
SOCKET newsock;
SOCKADDR_IN client_addr;
int len, i;
len = sizeof(client_addr);
#if defined (WIN32)
memset(&addr, 0, sizeof(addr));
#elif defined (LINUX)
bzero((char *)&client_addr, len);
#endif
if ((newsock = accept(ssocket->DaemonSock, (SOCKADDR *)&client_addr, &len)) == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("\n");
printf("Accept client %s in function MyAccept() failed!\n", inet_ntoa(client_addr.sin_addr));
printf("\n");
#endif
return (-1);
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("\n");
printf("Accept client %s in function MyAccept() successed,\n", inet_ntoa(client_addr.sin_addr));
printf("and the new socket to connect this IP is %d\n", newsock);
printf("\n");
#endif
}
FilterDoubleClient(ssocket, &client_addr);
if (!setsocketmode(newsock, 1))//set to no block mode
{
#if defined (SOCKCOMP_DEBUG)
printf("\n");
printf("Set socket %d to no block mode in function MyAccept() failed!\n", newsock);
printf("\n");
#endif
return (-2);
}
if (!masknagle(newsock, RIGHT))//set socket to no_delay mode
{
#if defined (SOCKCOMP_DEBUG)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -