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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31955514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:03:41  来源:igfitidea点击:

Simple UDP socket code, sending and receiving messages

c++csocketsudp

提问by forever_fighting_21

I am just learning UDP sockets and this is my first code involving it. I have two programs which send and receive messages back and forth. My question is it seems I have to declare which IP address I am sending/receiving from multiple times throughout the code as it changes but I feel there is a better way to do this without changing the inet_addr manually within the codes. From my reading it looks like sendto and recvfrom may be able to help but I am unsure how to use them in this context. If anyone could show me how to fix my simple problem I would greatly appreciate it! Thanks

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

CODE 1: Send then Receive

代码 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);

}

CODE 2: Receive then Send

代码 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);
}

回答by slangley

If you use the function recvfrom()

如果您使用函数 recvfrom()

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

What this function does is it fills a structure of sockaddr with the IP and port information of the packet that it has just received. For example, if your code that sends first then receives sends a packet to the receiver, the receiver should be able to fill the structure values of sin_addr and sin_port with the correct values. You can then make a call of sendto() with this information in order to send it to the correct machine.

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

Here's the man pages for these functions:

以下是这些功能的手册页:

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

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

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

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

回答by Aditya Kothari

Try using this:

尝试使用这个:

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

127.0.0.1 is the loopback IP. The address is used to establish an IP connection to the same machine, which seems to be your case.

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

A detailed way to solve the problem can be found here

可以在这里找到解决问题的详细方法