使用 UDP 联网

发布于 2025-01-04 02:18:44 字数 204 浏览 0 评论 0原文

使用 sendto() 将 UDP 数据包发送到主机时会发生什么。 我发送的所有位都已发送(从返回值可知)。我立即使用recvfrom(),它不输出任何内容,但程序不退出(即没有返回值)。

我认为如果没有收到回复,程序必须退出。

来自端口的 UDP 数据包的回复是什么。

这个数据包被防火墙阻止了吗?如果是的话为什么sendto的返回值是非负的。

what happens when a UDP packet is sent to a host using sendto().
all the bits i am sending are sent(known from the return value).immediately i use a recvfrom() which does not output anything but program do not exit(i.e no return value).

I think that the program must exit if no reply is recieved.

what will the replies for a UDP packet from a port.

is this packet blocked by firewall?? if yes then why is the return value of sendto is non-negative.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏末的微笑 2025-01-11 02:18:44

recvfrom() 将阻塞,直到收到消息为止,除非将套接字设置为非阻塞。

您要查找的接口是

  • ioctl()FIONBIOO_NONBLOCK(取决于您的平台)、
  • select() 等待数据到达,或者一段时间后超时

另请记住,sendto() 的地址和端口号通常是网络字节顺序,因此请查看 ntohlntohs

recvfrom() will block until a message is received unless you set the socket to non-blocking.

The interfaces you want to look for are

  • ioctl() with FIONBIO or O_NONBLOCK (depending your platform),
  • select() to wait for data to arrive, or timeout after a while

Also remember that the address and port number for sendto() usually be network-byte order, so look into ntohl and ntohs.

汐鸠 2025-01-11 02:18:44

您的客户端或服务器一定有错误。首先尝试本地主机,这样你就可以避免防火墙问题

这是我用于测试的非阻塞udp客户端/服务器的示例,它使用ioctl()来检查套接字上是否有数据要读取,但是如果你想做一些使用 epoll 的严肃应用程序会更有效,您也可以指定以微秒为单位等待的超时:

[null@localhost tests]$ cat udpserv.c 
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>

#define BUFLEN 512
#define NPACK 15
#define PORT 9930

void diep(char *s)
{
  printf("erno=%d errstr=%s\n",errno,strerror(errno));
  perror(s);
  exit(1);
}

int main(void)
{
  struct sockaddr_in si_me, si_other;
  int s,ret,nbytes, i, slen=sizeof(si_other);
  char buf[BUFLEN];

  if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    diep("socket");

  memset((char *) &si_me, 0, sizeof(si_me));
  si_me.sin_family = AF_INET;
  si_me.sin_port = htons(PORT);
  si_me.sin_addr.s_addr = htonl(INADDR_ANY);
  if (bind(s,  (struct sockaddr*) &si_me, sizeof(si_me))==-1)
      diep("bind");

  fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK);
  sleep(10);  
  for (i=0; i<NPACK; i++) {
    ret=ioctl(s,FIONREAD,&nbytes);
    if (ret==-1) {
        printf("error on FIONREAD\n");
    } else {
        printf("nbytes=%d\n",nbytes);
    }
    if (recvfrom(s, buf, BUFLEN, 0,  (struct sockaddr*) &si_other, &slen)==-1)
      diep("recvfrom()");
    printf("Received first half of packet from %s:%d\nData: %s\n\n", 
           inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
  }

  close(s);
  return 0;

}



[null@localhost tests]$ cat udpclient.c 
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#define SRV_IP "127.0.0.1"
#define BUFLEN 200
#define NPACK 10
#define PORT 9930

/* diep(), #includes and #defines like in the server */
void diep(char *s)
{
  perror(s);
  exit(1);
}

int main(void)
{
  struct sockaddr_in si_other;
  int s, i, slen=sizeof(si_other);
  char buf[BUFLEN];

  if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    diep("socket");

  memset((char *) &si_other, 0, sizeof(si_other));
  si_other.sin_family = AF_INET;
  si_other.sin_port = htons(PORT);
  if (inet_aton(SRV_IP, &si_other.sin_addr)==0) {
    fprintf(stderr, "inet_aton() failed\n");
    exit(1);
 }

 for (i=0; i<NPACK; i++) {
    printf("Sending packet %d\n", i);
    sprintf(buf, "This is packet %d\n", i);
    if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, slen)==-1)
      diep("sendto()");
 }

 close(s);
 return 0;
}

sendto() 是非负数,因为它返回发送的字节数。检查 sendto 的手册页

you must have some error in your client or server. try localhost first, so you avoid firewall problems

this is an example of nonblocking udp client/server I was using for my tests, it uses ioctl() to check if there is data to read on the socket, however if you want to do some serious application using epoll would be more efficient also you can specify timeout to wait in microseconds:

[null@localhost tests]$ cat udpserv.c 
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>

#define BUFLEN 512
#define NPACK 15
#define PORT 9930

void diep(char *s)
{
  printf("erno=%d errstr=%s\n",errno,strerror(errno));
  perror(s);
  exit(1);
}

int main(void)
{
  struct sockaddr_in si_me, si_other;
  int s,ret,nbytes, i, slen=sizeof(si_other);
  char buf[BUFLEN];

  if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    diep("socket");

  memset((char *) &si_me, 0, sizeof(si_me));
  si_me.sin_family = AF_INET;
  si_me.sin_port = htons(PORT);
  si_me.sin_addr.s_addr = htonl(INADDR_ANY);
  if (bind(s,  (struct sockaddr*) &si_me, sizeof(si_me))==-1)
      diep("bind");

  fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK);
  sleep(10);  
  for (i=0; i<NPACK; i++) {
    ret=ioctl(s,FIONREAD,&nbytes);
    if (ret==-1) {
        printf("error on FIONREAD\n");
    } else {
        printf("nbytes=%d\n",nbytes);
    }
    if (recvfrom(s, buf, BUFLEN, 0,  (struct sockaddr*) &si_other, &slen)==-1)
      diep("recvfrom()");
    printf("Received first half of packet from %s:%d\nData: %s\n\n", 
           inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
  }

  close(s);
  return 0;

}



[null@localhost tests]$ cat udpclient.c 
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#define SRV_IP "127.0.0.1"
#define BUFLEN 200
#define NPACK 10
#define PORT 9930

/* diep(), #includes and #defines like in the server */
void diep(char *s)
{
  perror(s);
  exit(1);
}

int main(void)
{
  struct sockaddr_in si_other;
  int s, i, slen=sizeof(si_other);
  char buf[BUFLEN];

  if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    diep("socket");

  memset((char *) &si_other, 0, sizeof(si_other));
  si_other.sin_family = AF_INET;
  si_other.sin_port = htons(PORT);
  if (inet_aton(SRV_IP, &si_other.sin_addr)==0) {
    fprintf(stderr, "inet_aton() failed\n");
    exit(1);
 }

 for (i=0; i<NPACK; i++) {
    printf("Sending packet %d\n", i);
    sprintf(buf, "This is packet %d\n", i);
    if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, slen)==-1)
      diep("sendto()");
 }

 close(s);
 return 0;
}

the sendto() is non negative because it returns number of bytes sent. check the man page for sendto

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文