接收UDP数据包到绑定的客户端地址

时间:2013-08-07 02:14:07

标签: c udp ip client-server bind

概述

编写一个客户端 - 服务器应用程序,该应用程序使用基于UDP的UDP在Linux上的C上进行通信以进行comp.sci。大学项目。

网络设置很棘手:客户端和服务器都需要绑定本地IP地址。当客户端尝试绑定IP地址时,服务器能够确定客户端的IP地址,但无法接收任何数据包。当客户端不执行绑定时,客户端和服务器通信几乎完美,但服务器无法确定客户端的IP地址。

客户端+服务器代码

以下是绑定的客户端代码:

* 编辑:在建议*

的函数调用下向上移动perror
   if (bind(client_socket.sockfd, (struct sockaddr *) &(client_socket.client_addr), 
      sizeof(client_socket.client_addr)) < 0){
    perror("error on binding!"); 
    debug(("client: bind"),__LINE__, __FILE__);
    close(client_socket.sockfd);
    return -1;
  }

以下是打开套接字的客户端和服务器代码:

int RDP_getSock(char *server_addr, char *server_port, rdp_socket *rsocket){
  rsocket->sockfd = socket(AF_INET, SOCK_DGRAM, 0);

  if(rsocket->sockfd <0 ){
    return -1;
  }

  bzero(&(rsocket->server_addr),sizeof(rsocket->server_addr));
  rsocket->server_addr.sin_family = AF_INET;
  rsocket->server_addr.sin_port = htons(atoi(server_port));

  if(server_addr != NULL){
    rsocket->server_addr.sin_addr.s_addr = inet_addr(server_addr);

    if( rsocket->server_addr.sin_addr.s_addr <0 ){
      return -1;
    }

  }

  rsocket->connected = 0;
  return 0;
}

客户端称之为:

  if(RDP_getSock(argv[3], argv[4], &client_socket) <0 ){
        perror("client: error on RDP_getSock()");
        return -1;
    }

服务器调用它:

  if(RDP_getSock( NULL, argv[2], &server_socket) == -1 ){
        perror("server: error on RDP_getSock()");
        return -1;
    }  

当客户端尝试发送到服务器时,将显示以下错误消息:

receive ACK error: Resource temporarily unavailable
EAGAIN error
: Resource temporarily unavailable

从服务器读取的代码(类似于从客户端读取的代码):

ssize_t RDP_receive_from_server(rdp_socket *rsocket, rdp_packet *packet){
  socklen_t address_length = sizeof( struct sockaddr_in );
  bzero(&(rsocket->server_addr), address_length);
  bzero(packet->header.type, RDP_HEADER_TYPE_SIZE);


  return recvfrom(rsocket->sockfd, packet, MAX_PACKET_SIZE, 0, (struct sockaddr*)&(rsocket->server_addr), &address_length);
}

客户端和服务器上都设置了超时。但是,由于客户端和服务器在技术上是在同一台机器上,我无法理解为什么强制客户端绑定到本地IP地址失败。

实际发送数据包的代码(进出客户端/服务器):

ssize_t RDP_send_packet(rdp_socket *rsocket, rdp_packet *packet, int to_client){
  ssize_t result = -1;
  socklen_t address_length = sizeof( struct sockaddr_in );
  char src_ip[256];
  char dest_ip[256];
  bzero(src_ip, 256);
  bzero(dest_ip,256);

  if(to_client){
    debug(("send to client"),__LINE__, __FILE__);
    result = sendto(rsocket->sockfd, packet, sizeof(struct RDP_packet), 0,
        (struct sockaddr *)&(rsocket->client_addr),sizeof(rsocket->client_addr));

    // inet_ntoa(rsocket.client_addr.sin_addr), ntohs(server_socket.client_addr.sin_port));

    strncpy(src_ip, inet_ntoa(rsocket->server_addr.sin_addr), 256);
    debug(src_ip,__LINE__, __FILE__);

    strncpy(dest_ip, inet_ntoa(rsocket->client_addr.sin_addr), 256);
    debug(dest_ip,__LINE__, __FILE__);

    RDP_logline(
      's',
      src_ip,
      ntohs(rsocket->server_addr.sin_port),
      dest_ip,
      ntohs(rsocket->client_addr.sin_port),
      packet->header.type,
      packet->header.seq );     
  }
  else{
    debug(("send to server"),__LINE__, __FILE__);
    result = sendto(rsocket->sockfd, packet, sizeof(struct RDP_packet), 0,
        (struct sockaddr *)&(rsocket->server_addr),sizeof(rsocket->server_addr));  

    strncpy(src_ip, inet_ntoa(rsocket->client_addr.sin_addr), 256);
    debug(src_ip,__LINE__, __FILE__);

    strncpy(dest_ip, inet_ntoa(rsocket->server_addr.sin_addr), 256);
    debug(dest_ip,__LINE__, __FILE__);

    RDP_logline(
      's',
      src_ip,
      ntohs(rsocket->client_addr.sin_port),
      dest_ip,
      ntohs(rsocket->server_addr.sin_port),
      packet->header.type,
      packet->header.seq );        
  }

  debug(("send complete"),__LINE__, __FILE__);
  return result;
}

记录显示IP地址

以下是来自客户端的日志行,显示客户端IP /端口和服务器IP /端口,并在客户端上绑定(IP地址192.168.1.100是预期值):

2013-08-06 18:47:27.433176 s 192.168.1.100:8080 10.10.1.100:9090 SYN 1

从服务器端:

2013-08-06 18:52:30.321409 s 0.0.0.0:9090 0.0.0.0:0 ACK 1

来自客户端的日志行,显示客户端IP /端口和服务器IP /端口,没有绑定:

2013-08-06 19:22:17.613885 s 176.39.64.0:0 10.10.1.100:9090 ACK 2

从服务器:

2013-08-06 19:22:17.613858 s 0.0.0.0:9090 10.10.1.100:37887 FIN 2

当客户端没有使用bind时,看似分配给客户端的IP地址和端口是随机的(例如,176.39.64.0:0)。

问题

为什么绑定客户端的任何想法阻止服务器发回ACK数据包?

0 个答案:

没有答案