【问题标题】:C UDP client and server on remote hosts远程主机上的 C UDP 客户端和服务器
【发布时间】:2015-01-05 03:41:11
【问题描述】:

我写了一个简单的 C UDP 客户端和服务器,客户端向服务器发送一个字符。在同一台电脑上一切正常。所以我想将一个角色发送到远程电脑。不幸的是,它不起作用:服务器没有收到任何东西,但使用wireshark 我可以看到数据包正在发送到正确的目的地。

代码如下: (servip 包含服务器的地址)

//client
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

#define SERV_PORT 50000
int main(){

  int id, s;
  char buf;
  char servip[] = "...";
  id = socket(AF_INET,SOCK_DGRAM,0);
  buf = 'a';
  struct sockaddr_in servaddr;
  memset((void *)&servaddr, 0, sizeof(servaddr));

  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(SERV_PORT);
  inet_pton(AF_INET,servip, &servaddr.sin_addr); //controlla se minore di 0

  s = sendto(id,&buf,sizeof(char),0,(struct sockaddr *) &servaddr,sizeof(servaddr));
  if (s == 0)
    fprintf(stderr,"errore in sendto");

  return EXIT_SUCCESS;
}



//server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define SERV_PORT 50000
int main(){
  int id, s;
  unsigned int len;
  char buf;
  id = socket(AF_INET,SOCK_DGRAM, 0);
  struct sockaddr_in addr;
  memset((void *)&addr, 0, sizeof(addr));

  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_ANY); /* il server accetta pacchetti su
  una qualunque delle sue interfacce di rete */
  addr.sin_port = htons(SERV_PORT); /* numero di porta del server */
  len = sizeof(addr);

  bind(id, (struct sockaddr *) &addr, sizeof(addr));

  s = recvfrom(id,&buf,sizeof(char),0,(struct sockaddr *) &addr,&len);

  printf("%c\n",buf);

  if (s==0)
    fprintf(stderr,"errore in recvfrom");



  return EXIT_SUCCESS;
}

有人可以帮我吗?我究竟做错了什么?您能否为我提供一个实际在远程主机上工作的 UDP 服务器和客户端的示例? 提前致谢。

【问题讨论】:

  • 你把什么作为服务器IP?这个远程主机在哪里?您是否能够从您尝试发送消息的主机 ping 远程主机?
  • -作为服务器IP,我使用whatsmyip.org提供的IP -基本上我使用我的电脑作为服务器,我朋友的电脑作为客户端。 - 我没有尝试 ping 远程主机。一会儿我会的,谢谢你的建议

标签: c sockets udp


【解决方案1】:

首先,您应该测试“bind”、“recvfrom”和“sendto”的每个状态,如果发生错误,它们都会返回“-1”。双方,客户端和服务器。 您还应该检查变量全局变量 errno 的状态以了解发生的错误。

也检查您的防火墙。如果您不在同一主机上使用客户端和服务器,请在客户端和服务器上尝试使用wireshark。

添加标头 errno 以检查 errno。

#include <errno.h>

.
.
.
if (sendto(id,&buf,sizeof(char),0,(struct sockaddr *) &servaddr,sizeof(servaddr))== -1) {
int errsv = errno;
printf("sendto() failed\n");
if (errsv == ...) { ... }
}
.

【讨论】:

    【解决方案2】:

    我怀疑你会想bind 到一个套接字来设置源地址和端口:

    struct sockaddr_in myaddr;
    memset((char *)&myaddr, 0, sizeof(myaddr));
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    myaddr.sin_port = htons(0);
    
    if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
        perror("bind failed");
        exit (1);
    }
    

    如果wireshark 显示数据包已传输,您能否确认它也显示服务器正在接收数据包?这应该有助于消除防火墙和路由问题。

    【讨论】:

    • 我会尽快插入 bind 并告诉你:) 谢谢!
    • 是的,我打开了路由器上的端口,一切正常! :)
    • @Simus 随时接受/+1 答案然后:-)
    猜你喜欢
    • 2012-04-11
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    • 2015-01-09
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    相关资源
    最近更新 更多