C套接字可以与客户端通信,但不能使用recvfrom提取客户端IP地址

时间:2019-01-14 01:38:12

标签: c sockets tcpserver recvfrom sockaddr

使用C进行套接字编程。代码在服务器端运行。代码功能正常,可以与127.0.0.1(localhost)和其他机器通信。但是在recvfrom()调用之后无法提取客户端IPv4地址和端口号。我认为通信是一种很好的手段,recvfrom成功地将客户端地址写入clientAddr,但是由于某种原因我无法将其打印出来。 getpeername()函数有效,但是我只想知道为什么在recvfrom()调用后无法获得正确的地址和端口号。

使用-ggdb -Wall -std = c11标志编译该代码。没有警告。在Ubuntu 18.04LTS上运行。以下是一些我认为相关的代码。

#include <arpa/inet.h> // To use inet_ntoa

#define ADDR_LEN sizeof(struct sockaddr)
#define MAX_DATA_SIZE 1024

Some code for accept connection and select the right file descirptor as 
commSockFd.     

char data[MAX_DATA_SIZE];
struct sockaddr_in clientAddr;
socklen_t clientAddrLen = ADDR_LEN;
printf("clientAddrLen before recvfrom() %d\n", clientAddrLen);   

int sentRecvBytes = recvfrom(commSockFd, data, sizeof(data), 0, 
  (struct sockaddr*)&clientAddr, (&clientAddrLen));
printf("clientAddrLen after recvfrom() %d\n", clientAddrLen);    
printf("Server received %d bytes from client %s:%u\n",sentRecvBytes,
  inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));

struct sockaddr_in peerAddr;
socklen_t peerLen = ADDR_LEN;
getpeername(commSockFd, (struct sockaddr*)&peerAddr,&peerLen);
printf("Result of getpeername, ip and port: %s  %hu\n", 
  inet_ntoa(peerAddr.sin_addr), ntohs(peerAddr.sin_port));

上面的代码打印结果为:

Connection accepted from client: 192.168.70.112:4903
Blocked on select system call...
clientAddrLen before recvfrom() 16
clientAddrLen after recvfrom() 0
Server received 8 bytes from client 254.127.0.0:47010
Result of getpeername, ip and port: 192.168.70.112  4903

奇怪的事情是: 1. recvfrom之后将clientAddrLen设置为0,根据documentation,我认为应该为8左右。至少有一些正数。 2.在调用recvfrom()之后,它无法从clientAddr打印客户端IP地址和端口号,这是主要问题。但是,使用getpeername可以得到正确的结果。

在此先感谢您的帮助!

0 个答案:

没有答案