简单的UDP套接字代码,发送和接收消息

Posted

技术标签:

【中文标题】简单的UDP套接字代码,发送和接收消息【英文标题】:Simple UDP socket code, sending and receiving messages 【发布时间】:2015-08-12 03:26:46 【问题描述】:

我只是在学习 UDP 套接字,这是我第一个涉及它的代码。我有两个程序来回发送和接收消息。我的问题是,我似乎必须声明我在整个代码中多次发送/接收的 IP 地址,因为它发生了变化,但我觉得有一种更好的方法可以做到这一点,而无需在代码中手动更改 inet_addr。从我的阅读来看, sendto 和 recvfrom 可能会有所帮助,但我不确定如何在这种情况下使用它们。如果有人能告诉我如何解决我的简单问题,我将不胜感激!谢谢

代码 1:发送然后接收

int main(int argc, char *argv[])

//initialize socket and structure
int socket_info;
struct sockaddr_in server;
char message[100];
char incoming_message[100];

printf("Input Message: ");
fgets(message, 100, stdin);

    //create socket
    socket_info = socket(AF_INET, SOCK_DGRAM, 0);
    if (socket_info == -1) 
    printf("Could not create socket");
    

//assign local values
    server.sin_addr.s_addr = inet_addr("172.21.8.178");
    server.sin_family = AF_INET;
    server.sin_port = htons( 1100 );

    //binds connection
    if (bind(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0)     
perror("Connection error");
       return 1;
    
    puts("Bind");

    //assign new value to connect to
    server.sin_addr.s_addr = inet_addr("172.21.8.179");

    //checks connection 
    if (connect(socket_info, (struct sockaddr *)&server, sizeof(server)) <       0) 
    perror("Connection error");
       return 1;
    
    puts("Connected");

    //sends message
if(send(socket_info, message, strlen(message), 0) <0)         
perror("Send failed");
    return 1;
    
    puts("Message Sent");

//receives message back    
if(recv(socket_info, incoming_message, sizeof(incoming_message), 0) <0)     
puts("Received failed");
    return 1;
    
    puts("Message received");
    puts(incoming_message);

close(socket_info);


代码 2:接收然后发送

int main(int argc, char *argv[])

//initialize socket and structure
int socket_info;
struct sockaddr_in server;
char incoming_message[100];

    //create socket
    socket_info = socket(AF_INET, SOCK_DGRAM, 0);
    if (socket_info == -1) 
    printf("Could not create socket");
    

    //assign values
    server.sin_addr.s_addr = inet_addr("172.21.8.179");
    server.sin_family = AF_INET;
    server.sin_port = htons( 1100 );

    //checks connection
    if (bind(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0) 
    perror("Connection error");
       return 1;
    
    puts("Bind");

    //Receive an incoming message
if( recv(socket_info, incoming_message, sizeof(incoming_message), 0) < 0)       
puts("Received failed");
    return 1;
    
    puts("Message received");
    puts(incoming_message);

server.sin_addr.s_addr = inet_addr("172.21.8.178");

if (connect(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0) 
    perror("Connection error");
     return 1;
    
    puts("Connected");

//Sends message back
char message[100];

printf("Input Message: ");
fgets(message, 100, stdin);

if(send(socket_info, message, strlen(message), 0) <0)         
perror("Send failed");
    return 1;
    
    puts("Message Sent");

close(socket_info);

【问题讨论】:

绑定未连接,在绑定错误上打印“连接错误”只会误导自己。您可以使用 sendto() 代替连接套接字。 我认为连接 API 用于 TCP 套接字。它在这里有什么用途? 对于 UDP 套接字程序,您无需使用 connect。它不是正确的 UDP 代码。看看简单的 echo server。它会对您有所帮助。 @NaveenKumar 没必要但有可能,而且这样做并不是编码不当。 这看起来更像是一个隐藏在 SOCK_DGRAM 后面的 TCP 套接字 【参考方案1】:

如果你使用函数recvfrom()

    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
             struct sockaddr *src_addr, socklen_t *addrlen);

这个函数的作用是用它刚刚收到的数据包的 IP 和端口信息填充 sockaddr 的结构。例如,如果您的代码先发送然后接收发送一个数据包给接收器,接收器应该能够用正确的值填充 sin_addr 和 sin_port 的结构值。然后,您可以使用此信息调用 sendto(),以便将其发送到正确的机器。

这里是这些函数的手册页:

https://linux.die.net/man/2/recvfrom

https://linux.die.net/man/2/sendto

【讨论】:

【参考方案2】:

试试这个:

inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)

127.0.0.1 是环回 IP。该地址用于建立与同一台机器的 IP 连接,这似乎是您的情况。

解决问题的详细方法可以找here

【讨论】:

以上是关于简单的UDP套接字代码,发送和接收消息的主要内容,如果未能解决你的问题,请参考以下文章

Java中使用UDP实现简单的聊天功能

udp网络程序-发送接收数据

udp网络程序-发送接收数据

C#中UDP(Socket)

UDP和套接字,recvfrom()返回-1,资源暂时不可用

QT下UDP套接字通信——QUdpSocket 简单使用