使用select处理多个客户端

时间:2014-11-30 13:51:26

标签: sockets select udp serversocket

因为我已经问了类似的问题,但没有得到解决方案。因此我用整个代码再次提出这个问题。请告诉我如何实现这一目标

1)我有一个客户端向主服务器(127.0.0.1)发送消息,主服务器将其转发到server2(127.0.0.2)

2)Server2向主服务器发送消息,主服务器将消息转发给客户端。

问题1):虽然我从客户端收到数据,但它们没有发送到server2。 问题2):我没有收到来自server2的任何数据

    //SERVER
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/select.h>//use select() for multiplexing
#include <sys/fcntl.h> // for non-blocking

#define MAX_LENGTH 100000
#define PORT 1901

/* Select() params
 * int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
 * FD_SET(int fd, fd_set *set);
 * FD_CLR(int fd, fd_set *set);
 * FD_ISSET(int fd, fd_set *set);
 * FD_ZERO(fd_set *set);
*/

void error(char *message)
{
    perror(message);
    exit(1);
}

int main()
{

  // select parameters declared
  fd_set original_socket;
  fd_set original_stdin;
  fd_set readfds;
  fd_set writefds;
  struct timeval tv;
  int numfd, numfd2;

  // socket parameters declared
  int socket_fd_ob, socket_fd_hm;
  int bytes_read, bytes_sent;
  char address_length, address_length2;
  char recieve_data[MAX_LENGTH];
  char send_data[MAX_LENGTH];
  struct sockaddr_in server_address_ob, server_address_hm, client_address;
  int z = 0;

  //Socket creation done separately for both OBCU and HM communications
  if ((socket_fd_ob = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 
  {
      error("socket()");
  }
  if ((socket_fd_hm = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 
  {
      error("socket()");
  }


  fcntl(socket_fd_ob, F_SETFL, O_NONBLOCK); //set socket to non-blocking
  fcntl(socket_fd_hm, F_SETFL, O_NONBLOCK); //set socket to non-blocking

  // clear the set ahead of time
  FD_ZERO(&original_socket);
  FD_ZERO(&original_stdin);
  FD_ZERO(&readfds);
  FD_ZERO(&writefds);

  // add our descriptors to the set (0 - stands for STDIN)
  FD_SET(socket_fd_ob, &original_socket);//instead of 0 put socket_fd_ob
  FD_SET(socket_fd_ob, &readfds);
  FD_SET(0,&original_stdin);
  FD_SET(0, &writefds);

  // the n param in select()
  numfd  = socket_fd_ob + 1;
  numfd2 = socket_fd_hm + 1;


  // wait until either socket has data ready to be recv()d (timeout 10.5 secs)
  tv.tv_sec = 0.7;
  tv.tv_usec = 500000;

  server_address_ob.sin_family = AF_INET;
  server_address_ob.sin_port = htons(1901);
  server_address_ob.sin_addr.s_addr = inet_addr("127.0.0.1");
  bzero(&(server_address_ob.sin_zero),sizeof(server_address_ob));

  server_address_hm.sin_family = AF_INET;
  server_address_hm.sin_port = htons(1901);
  server_address_hm.sin_addr.s_addr = inet_addr("127.0.0.2");
  bzero(&(server_address_ob.sin_zero),sizeof(server_address_hm));

  // Bind socket to the particular addresses

  if (bind(socket_fd_ob,(struct sockaddr *)&server_address_ob, sizeof(struct sockaddr)) == -1)
  {
      error("bind()");
  }

  if (bind(socket_fd_hm,(struct sockaddr *)&server_address_hm, sizeof(struct sockaddr)) == -1)
  {
      error("bind()");
  }

  address_length  = sizeof(struct sockaddr);
  address_length2 = sizeof(struct sockaddr);

  printf("\nMain server waiting for client to respond...\n");
  fflush(stdout);

  while (1)
  {
    readfds = original_socket;
    writefds = original_stdin;//problem
    int recieve = select(numfd, &readfds, &writefds,/*NULL,*/ NULL, &tv);
    int sent    = select(numfd2, &readfds, &writefds,/*NULL,*/ NULL, &tv);

    if (recieve == -1 || sent == -1) 
    {
      perror("select"); // error occurred in select()
    } 
    else if (recieve == 0 || sent == 0) 
    {
      printf("Timeout occurred!  No data after 1.5 seconds.\n");
    } 
    else 
    {
        // one or both of the descriptors have data
        if (FD_ISSET(socket_fd_ob, &readfds)) //if set to read
        { 
          FD_CLR(socket_fd_ob, &readfds);

        if (bytes_read = recvfrom(socket_fd_ob,recieve_data,MAX_LENGTH,0,(struct sockaddr *)&server_address_ob, &address_length)>0)
        {       
        for (z = 0; z < bytes_read; ++z) {
          FD_ISSET(socket_fd_hm, &writefds);
          FD_CLR(socket_fd_hm, &writefds);
          //recvfrom speech recognition client and decide what to send to HM accordingly..
          send_data[bytes_read] = recieve_data[bytes_read];
          //block call, will wait till client enters something, before proceeding
          //send the corresponding to HM
          bytes_sent = sendto(socket_fd_hm,send_data,strlen(send_data)+1,0,(struct sockaddr *)&server_address_hm, &address_length2); 
          fflush(stdout);
       }                  

          // 02x, #x,X
          printf("\n(%s , %d) rcvd: %s\n",inet_ntoa(server_address_ob.sin_addr),ntohs(server_address_ob.sin_port),recieve_data);
          printf("\n(%s , %d) sent: %s\n",inet_ntoa(server_address_hm.sin_addr),ntohs(server_address_hm.sin_port),send_data);
          recieve_data[bytes_read] = '\0'; //add null to the end of the buffer
          send_data[bytes_read] = '\0'; //add null to the end of the buffer
        }

        else if (bytes_read = recvfrom(socket_fd_hm,recieve_data,MAX_LENGTH,0,(struct sockaddr *)&server_address_hm, &address_length)>0)
        {       
       for (z = 0; z < bytes_read; ++z) {
          FD_ISSET(socket_fd_ob, &writefds);
          FD_CLR(socket_fd_ob, &writefds);
          send_data[bytes_read] = recieve_data[bytes_read];
          //block call, will wait till client enters something, before proceeding
          //send the corresponding to HM
          bytes_sent = sendto(socket_fd_ob,send_data,strlen(send_data)+1,0,(struct sockaddr *)&server_address_ob, &address_length2); 
          fflush(stdout);
       }                  

          // 02x, #x,X
          printf("\n(%s , %d) rcvd: %s\n",inet_ntoa(server_address_hm.sin_addr),ntohs(server_address_hm.sin_port),recieve_data);
          printf("\n(%s , %d) sent: %s\n",inet_ntoa(server_address_ob.sin_addr),ntohs(server_address_ob.sin_port),send_data);
          recieve_data[bytes_read] = '\0'; //add null to the end of the buffer
          send_data[bytes_read] = '\0'; //add null to the end of the buffer
        }

        else
        {
        printf("error noted");
        }   
        }  //end if set to read




    } //end else
  }//end while

  close (socket_fd_ob);
  close (socket_fd_hm);
  return 0;
}

请为我提供代码示例。我是这个主题的新手,还没有广泛的观点。

由于

0 个答案:

没有答案