客户端套接字无法使用轮询/选择接收数据

标签 c linux sockets client-server

/* SEND FUNC. */
int mysend(unsigned char *buffer, int len) {

int     sock,ret;
int     status,flags;
struct sockaddr_in6 servaddr;
int opt = 1;
char *addr = "1101::1";

sock = socket(AF_INET6,SOCK_DGRAM,0);
if (sock < 0)
    return -1;
if( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) 
    return -1;
flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags|O_NONBLOCK);

servaddr.sin6_family = AF_INET6;
servaddr.sin6_port = htons(61616);

status = inet_pton(AF_INET6, addr, &servaddr.sin6_addr);
if (status <= 0) {
    perror("inet_pton");
    return -1;
}
/* send message to server */
status = sendto(sock, buffer, len, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
if (status < 0) {
    perror("sendto");
    return -1;
}
close(sock);
printf("MESSAGE SENT SUCCESSFULLY\n");
return 0;
}

/* RECEIVE FUNC. */
int myrcv() {


int     sock,ret;
int     status,len,rx_bytes;
int timeout,nfds =1;
struct sockaddr_in6 servaddr;
struct timeval wait;
unsigned char rxbuff[1024];
char *rcv;
char *addr = "1101::1";
fd_set rd;
struct pollfd *fds;


sock = socket(AF_INET6,SOCK_DGRAM,0);
if (sock < 0) 
    return -1;

servaddr.sin6_family = AF_INET6;
servaddr.sin6_port = htons(61616);

status = inet_pton(AF_INET6, addr, &servaddr.sin6_addr);
if (status <= 0) 
    return -1;
bind(sock,(struct sockaddr *)&servaddr,sizeof(servaddr));
timeout = (1* 1000);

wait.tv_sec = 10;
wait.tv_usec = 0;

len = sizeof(servaddr);
fds->fd = sock;
fds->events = POLLIN;

for(;;) {
  //FD_ZERO(&rd);
  //FD_SET(sock,&rd);

    printf("Waiting for data....\n");
    ret = poll(fds,nfds,timeout);

  //ret = select(1,&rd,NULL,NULL,&wait);
    if(ret < 0)
        break;
    if(fds->revents == 0)
      printf("revents 0 %d\n",ret);

    if(ret == 0)
       continue;

    memset(rxbuff,0,1024);
   //if(FD_ISSET(sock,&rd)) {
        printf("receiving message\n");
        rx_bytes = recvfrom(sock,rxbuff,1024,0,(struct sockaddr *)&servaddr,&len);
        memcpy(rcv,rxbuff,rx_bytes);
  //}      
}
close(sock);
return 0;
}

int main()
{
/* call mysend() periodically using sigaction() */
/* create a thread that continuously monitors(calls myrcv()) for incoming data */
    return 0;
}

我无法从服务器接收数据包,但我可以在 tcpdump 输出中看到数据包。以上是示例客户端代码片段,它尝试从服务器接收数据或向服务器发送数据。场景是:客户端需要定期向服务器发送数据,并且还应该能够从服务器接收任何数据。 我尝试过同时使用 poll 和 select 方法,但没有收到。如果我遗漏了什么,请告诉我。感谢您的支持。

最佳答案

您在接收时遇到的问题是您需要将接收套接字绑定(bind)到本地端口。

您还有其他可以改进的地方,比如为发送创建一个单一的套接字接收和在发送套接字上使用SO_REUSEADDR(写时不需要-仅套接字)。

你应该做的是:

  1. 创建套接字
  2. 设置套接字选项
  3. 绑定(bind)到本地地址(使用IN6ADDR_ANY_INIT绑定(bind)到所有接口(interface))
  4. 写入服务器
  5. 投票回复

关于客户端套接字无法使用轮询/选择接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12597647/

相关文章:

iphone - iPhone OS 4是否支持Web套接字?

c++ - 链接 : fatal error LNK1181: cannot open input file 'libclamav.lib'

android - 线程安全 RNG Android NDK

linux - statvfs 不支持的文件系统

C++/Linux : Dynamic Allocation produces two different error messages

java - 需要在Java应用程序和网页之间传递信息

python - Python3中的Socket,监听端口

c - 如何使用一个或多个参数从 bash 脚本运行 C 程序?

C printf 术语进度显示,并在下一行显示错误消息

c - DSP 的快速二维卷积