使用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可以得到正确的结果。
在此先感谢您的帮助!