在 C 中对 TCP 服务器使用 poll()

问题描述 投票:0回答:2

对于学校作业,我们必须制作一个传感器网关,该网关具有来自通过 TCP 连接的多个传感器的输入。我们收到了一个可用于 TCP 套接字的库。每当传感器节点断开连接时,就必须对其进行记录,并且必须调用某些数据函数。我使用 poll() 来复用网关的 I/O,但问题是它无法正常工作。我在下面制作了网关连接代码的原型。它有同样的问题,所以我认为我在 poll() 上做错了什么,但我不知道是什么。

这是我的服务器代码:

int main( void )
{
Socket server; 
Socket client[6];
int client_count = 0;
struct pollfd poll_list[7];

// open server socket
server = tcp_passive_open( PORT );
poll_list[0].fd = get_socket_descriptor( server ); 
poll_list[0].events = POLLIN;

while( 1 ) {    
  int retval, i;

  retval = poll(poll_list, client_count+1, 5000);
  if (retval > 0) {
      if (poll_list[0].revents && POLLIN > 0) {
          client[client_count] = tcp_wait_for_connection( server );
          poll_list[client_count+1].fd = get_socket_descriptor(client[client_count]);
          poll_list[client_count+1].events = POLLIN;
          client_count++;
      }    
      for (i=0; i<client_count+1;i++) 
  {
          if ( poll_list[i+1].revents & POLLIN)) 
      {
      printf("New message recieved.");
              tcp_receive(client[i], buffer, BUFFSIZE); 
      fflush(stdout);

          }
      if ( poll_list[i+1].revents & POLLHUP) 
      {
      printf("Client disconnected.");
              poll_list[client_count+1].fd = -1;
              poll_list[client_count+1].events = 0;
      fflush(stdout);   
          }
      }
  }
}

tcp_close( &server ); 
return 0;
}

这是客户端的代码:

int main( void ) {
Socket client;
char msg[] = "Hello there! Anyone?";

// open TCP connection to the server; server is listening to SERVER_IP and PORT
client = tcp_active_open( PORT, SERVER_IP ); 

// send msg to server
tcp_send( client, (void *)msg, strlen(msg)+1 ); 

printf("\n");  

// exit
tcp_close( &client );
return 1;
}

编辑:库文件的功能:

Socket tcp_passive_open(int port);
/* Creates a new TCP socket and opens the socket in 'passive listening mode' (waiting for an 
active connection setup request). The socket is bound to port number 'port' and to any 
IP address of the PC. The number of pending connection setup requests is set to the 
maximum. The newly created socket is return as the function result. This function is 
typically called by a server. */


Socket tcp_active_open(int remote_port, char *remote_ip );
/* Creates a new TCP socket and opens a TCP connection to a socket on the PC with IP address 
'remote_ip' on port 'remote_port'. The IP address that the host PC has to use to connect 
to the remote PC, is not defined (it is left to the system to choose an available IP       interface). 
The newly created socket is return as the function result. This function is typically 
called by a client. */


Socket tcp_wait_for_connection( Socket socket );
/* Puts the socket 'socket' in a blocking waiting mode. The function will only return 
when an incoming TCP connection setup request is received. The remote socket (the 
remote IP address and port number) that initiated the connection request is returned 
as the function result.  */


void tcp_close( Socket *socket );
/* The socket 'socket' is closed and any allocated resources are freed. */


void tcp_send(Socket socket, void *buffer, int bufsize );
/* The function initiates a send command on the socket 'socket'. Recall that the 
send command might block. In total 'bufsize' bytes of data in 'buffer' will be send. 
Of course, the socket 'socket' needs to be connected to a remote socket before this 
function can be called.  */

int tcp_receive (Socket socket, void* buffer, int bufsize);
/* The function initiates a receive command on the socket 'socket'. Recall that the 
receive command might block. Pending data in 'socket' will be copied to 'buffer'. The 
function returns the number of bytes that were really copied to 'buffer', which might 
be less than 'bufsize'. No more than 'bufsize' bytes however will be copied. Of course, 
the socket 'socket' needs to be connected to a remote socket before this function can 
be called.*/


char * get_ip_addr( Socket socket );
/* Returns the IP address to which the socket 'socket' is bound. The IP address is 
returned as a string. */

int get_port( Socket socket ); 
/* Returns the port number to which the socket 'socket' is bound. */

int get_socket_descriptor( Socket socket ); 
/* Returns the socket descriptor to which the socket 'socket' is bound. */

我得到的输出是这样的:

New message recieved.New message recieved.New message received....

代替:

New message received.
Client disconnected.

一直说有新消息,但是没有。这是非常令人沮丧的,因为在实际的网关中,程序正在处理不存在的数据。有谁知道我该如何解决这个问题?

提前致谢。

c sockets tcp
2个回答
1
投票

我希望这还不算太晚,但我相信

tcp_receive()
返回读取的字节数。您可以检查收到的值是否为零,而不是检查
POLLHUP
。如果是这样,您可以假设连接已关闭。

if (poll_list[i+1].revents & POLLIN)){
    if(tcp_receive(client[i], buffer, BUFFSIZE) == 0){
        printf("Client disconnected.\n");
        poll_list[client_count+1].fd = -1;
        poll_list[client_count+1].events = 0;
    }else{
        printf("New message recieved.\n");
    }
    fflush(stdout);
}

0
投票
 if (poll_list[0].revents && POLLIN > 0) 

&& -> &

© www.soinside.com 2019 - 2024. All rights reserved.