C中的UDP套接字

Ber*_*rez 5 c sockets udp

我正在为课堂上的家庭作业问题做准备.我想启动一个侦听文件请求的UDP服务器.它打开文件并使用UDP将其发送回请求客户端.

继承人的服务器代码.

    // Create UDP Socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("Can't create socket");
        exit(-1);
    }

    // Configure socket
    memset(&server, 0, sizeof server);
    server.sin_family = AF_INET; // Use IPv4
    server.sin_addr.s_addr = htonl(INADDR_ANY); // My IP
    server.sin_port = htons(atoi(argv[1])); // Server Port

    // Bind socket
    if ((bind(sockfd, (struct sockaddr *) &server, sizeof(server))) == -1) {
        close(sockfd);
        perror("Can't bind");
    }

    printf("listener: waiting to recvfrom...\n");
    if (listen(sockfd, 5) == -1) {
        perror("Can't listen for connections");
        exit(-1);
    }

while (1) {
    client_len = sizeof(struct sockaddr_in);
    newsockfd = accept(sockfd, (struct sockaddr*)&client,&client_len);

    if (newsockfd < 0) {
        perror("ERROR on accept");
    }

    // Some how parse request
    // I do I use recv or recvfrom?
    // I do I make new UDP socket to send data back to client?

    sendFile(newsockfd, filename);

    close(newsockfd);
}

close(sockfd);
Run Code Online (Sandbox Code Playgroud)

我有点迷失了如何从客户端收集数据?以及如何将新的UDP连接重新发送回客户端?

小智 12

UDP与TCP的不同之处:

  • 面向消息,而不是面向流.你不读/写或发送/ recv.你发送到/接收.消息的大小限制为64K.每次对recvfrom的调用都会通过调用sendto发送一条消息.如果recvfrom传递的缓冲区小于消息的大小,那么剩下的消息就会消失.

  • 没有联系.因此没有收听/接受/连接.您将消息发送到特定的地址/端口.当您收到消息时(在您的套接字绑定到的地址/端口上),您将传入消息的源作为recvfrom的输出参数.

  • 没有保证.消息可以不按顺序丢弃或接收.如果我没记错的话,它们不能被截断.

最后一点需要注意的是 - 您可能会发现自己正在通过UDP重新发明TCP.在这种情况下,停止并返回TCP.


Rob*_*rma 12

在C中编写了一个UDP服务器客户端,客户端发送了一个注册号,服务器给出了一个名称作为反馈.

服务器

0. Variable initialization
1. sock()
2. bind()
3. recvfrom()
4. sendto()
Run Code Online (Sandbox Code Playgroud)

客户

0. gethostbyname()
1. sock()
2. bzero()
4. sendto()
5. recvfrom()
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.您可以在这里找到udp server/client的示例代码


lee*_*roy 1

请记住,UDP 是无连接的。它仅发送数据包,不适合发送文件 - 除非整个内容适合一个 UDP 数据包。

如果您无论如何想要发送/接收 UDP 数据包,您只需使用适当的地址调用sendto / recvfrom即可。