MultiSocket侦听Linux套接字编程

时间:2014-01-21 11:19:20

标签: c linux sockets networking port

这是我编写的一个简单代码。服务器响应CONNECTIONS ON PORT 2923,2924和2925.

当我运行程序时,服务器只接受来自PORT 2923的CONNECTION。有人可以帮助我。 Thanku

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>

void handle_client(int cliend_fd)
{

  int ret = accept(cliend_fd, NULL, 0);
  if (ret < 0)
  {
    printf("Accept Error\n");
  }

  else
  {
    printf("Client Accepted\n");
    shutdown(ret, 2);
  }
}

int main()
{
  int count = 3;
  int PORT = 2923;

  struct sockaddr_in address;
  int MasterSocket[count];
  int i = 0;
  fd_set readfds;

  int maxfd;
  maxfd = -1;
  int SelectSession;

  struct timespec TimeOut;
  TimeOut.tv_sec = 2;
  TimeOut.tv_nsec = 2;

  for (i = 0; i < count; i++)
  {
    MasterSocket[i] = socket(AF_INET, SOCK_STREAM, 0);
  }

  for (i = 0; i < count; i++)
  {
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = PORT + i;
    if (bind(MasterSocket[i], (struct sockaddr *) &address, sizeof(address))
        < 0)
    {
      perror("Bind\n");
      getchar();
    }

    printf("SockerDesriptor %d---bind %d\n", MasterSocket[i], PORT + i);
  }

  for (i = 0; i < count; i++)
  {
    if (listen(MasterSocket[i], 4) < 0)
    {
      perror("Listen");
      getchar();
      //return 1;
    }
    else
    {
      printf("Listening on Port %d---\n", PORT + i);
    }
  }

  while (1)
  {
    FD_ZERO(&readfds);
    int status;

    for (i = 0; i < count; i++)
    {
      FD_SET(MasterSocket[i], &readfds);
      if (MasterSocket[i] > maxfd)
      {
        maxfd = MasterSocket[i];
      }
      printf("%d Added to FD_SET Descriptor %d \n\n", PORT + i,
          MasterSocket[i]);
    }

    //status = 0;
    printf("############Waiting for Connection\n");
    status = pselect(maxfd + 1, &readfds, NULL, NULL, &TimeOut, NULL );
    if (status < 0)
    {
      perror("Status");
      getchar();
      return 1;
    }

    else if (status == 0)
    {
      printf("TimeOut occured\n");
    }

    else
    {
      //printf("Status %d\n", status);
      SelectSession = -1;
      for (i = 0; i < count; i++)
      {
        //printf("Checking Set %d\n", i);
        if (FD_ISSET(MasterSocket[i], &readfds))
        {
          //printf("Matching Set %d\n", i);
          SelectSession = MasterSocket[i];
          printf("SelectSession %d\n", MasterSocket[i]);
          if (SelectSession == -1)
          {
            //shutdown (MasterSocket[i], 2);
            //continue;
            break;
          }
          else
          {
            printf("In Handle\n");
            handle_client(SelectSession);
            getchar();
          }

        }
        else
        {
          printf("Not in FD_ISSET\n");

        }
      }
    }

    /*for (i=0; i<count; i++)
     {
     shutdown (MasterSocket[i], 2);
     }
     */
  }

  return 0;
}

2 个答案:

答案 0 :(得分:2)

这一行

 address.sin_port = PORT + i;

应该是

 address.sin_port = htons(PORT + i);

确保端口以网络字节顺序存储。


如果你不再需要它,你应该在关闭它之后close()一个套接字描述符,以释放与之关联的系统资源。

答案 1 :(得分:1)

从while循环中删除getchar()

pselect服务器等待获取角色后,不再允许连接客户端。

或者你必须在连接每个客户端后在服务器中输入一个字符

使用htons

将端口号更改为网络字节顺序

程序:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>

void handle_client (int cliend_fd)
{
    int ret = accept(cliend_fd, NULL, 0);
    if ( ret < 0 )
        printf("Accept Error\n");
    else {
        printf ("Client Accepted\n");
        shutdown (ret, 2);
    }
    return;
}

int main()
{
    int count = 3, PORT = 8000, opt = 1, i = 0;
    int MasterSocket[count];
    int maxfd = -1, SelectSession;
    fd_set readfds;
    struct sockaddr_in address;

    struct timespec TimeOut;
    TimeOut.tv_sec = 2;
        TimeOut.tv_nsec = 2;

    for(i=0; i<count; i++)
    {
        MasterSocket[i] = socket(AF_INET , SOCK_STREAM , 0);
        printf("socket created : %d\n", MasterSocket[i]);
    }

    for(i=0; i<count; i++)
    {
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = inet_addr("192.168.1.4");
        address.sin_port = htons(PORT+i);
        if( setsockopt(MasterSocket[i], SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) {    
            perror("setsockopt1");
            return -1;
        }
        if (bind(MasterSocket[i], (struct sockaddr *)&address, sizeof(address)) < 0) {
            perror ("Bind\n");
            return -1;
        }
        printf("SockerDesriptor %d---bind %d\n", MasterSocket[i], PORT+i);
    }

    for(i=0; i<count;i++)
    {
        if (listen(MasterSocket[i], 4) < 0) {
                perror ("Listen\n");
                return -1;
        }
        else
            printf("Listening on Port %d---\n", PORT+i);    
    }

    while(1)
    {   
        FD_ZERO(&readfds);
        int status;
        for (i = 0; i < count; i++)
        {
            FD_SET(MasterSocket[i], &readfds);
            if (MasterSocket[i] > maxfd)
                maxfd = MasterSocket[i];
        }

        status = pselect(maxfd + 1, &readfds, NULL, NULL, &TimeOut, NULL );
        if(status < 0)
            perror("Status");
        /* else if(status == 0)
            printf("TimeOut occured\n"); */
        else if(status > 0) {
            for (i = 0; i < count; i++)
            {
                if (FD_ISSET(MasterSocket[i], &readfds)) {
                    SelectSession = MasterSocket[i];
                    printf("SelectSession %d\n", MasterSocket[i]);
                    handle_client(SelectSession);
                    //getchar();
                }
            }
        }
    }
    return 0;
}