⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serversock.c

📁 这个是服务器端的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -