编写一个客户端 - 服务器应用程序,该应用程序使用基于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地址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数据包?