UDP 套接字到套接字通信问题

问题描述 投票:0回答:1

UDP连接到socket后,客户端发送一条消息,服务器接收它,输出它,并尝试将他的消息发送给客户端。之后我想在客户端发这条消息,但是好像没有收到,请问是什么问题?

客户端发送消息后,服务器接收它,输出它,并尝试将他的消息发送给客户端。然后收到客户端发来的这条消息

这是客户端 udp 套接字。

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

#define BUF_SIZE 30
void error_handling(char *message);

int main(int argc, char *argv[])
{
    int sock;
    char message[BUF_SIZE];
    char clntmessage[BUF_SIZE];
    char servmessage[BUF_SIZE];
    int str_len;
    socklen_t adr_sz;
    
    struct sockaddr_in serv_adr, from_adr;
    if(argc!=3){
        printf("Usage : %s <IP> <port>\n", argv[0]);
        exit(1);
    }
    
    sock=socket(PF_INET, SOCK_DGRAM, 0);   
    if(sock==-1)
        error_handling("socket() error");
    
    memset(&serv_adr, 0, sizeof(serv_adr));
    serv_adr.sin_family=AF_INET;
    serv_adr.sin_addr.s_addr=inet_addr(argv[1]);
    serv_adr.sin_port=htons(atoi(argv[2]));
    
    while(1)
    {
        fputs("Insert message(q or Q quit): ", stdout);
        fgets(clntmessage, sizeof(message), stdin);   
        sendto(sock, clntmessage, strlen(clntmessage), 0,
            (struct sockaddr*)&serv_adr, sizeof(serv_adr));

        if (!strcmp(clntmessage, "q\n") || !strcmp(clntmessage, "Q\n")) {
            adr_sz = sizeof(from_adr);
            str_len = recvfrom(sock, servmessage, BUF_SIZE, 0,
                (struct sockaddr*)&from_adr, &adr_sz);
            printf("Message from server: %s", servmessage);
            if (!strcmp(servmessage, "bye\n"))
                break;
            else 
                servmessage[str_len] = 0;
                printf("Message from server: %s", servmessage);
                continue;
    }
    
    adr_sz=sizeof(from_adr);
    str_len=recvfrom(sock, servmessage, BUF_SIZE, 0, 
                (struct sockaddr*)&from_adr, &adr_sz);

    servmessage[str_len]=0;
    printf("Message from server: %s", servmessage);
}   
close(sock);
return 0;

}

void error_handling(char *message) {

    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

这是服务器 udp 套接字。

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

#define BUF_SIZE 30
void error_handling(char *message);

int main(int argc, char *argv[])
{
    int serv_sock;
    char send_message[BUF_SIZE];
    char recv_message[BUF_SIZE];
    int str_len;
    socklen_t clnt_adr_sz;
    
    struct sockaddr_in serv_adr, clnt_adr;
    if(argc!=2){
        printf("Usage : %s <port>\n", argv[0]);
        exit(1);
    }
    
    serv_sock=socket(PF_INET, SOCK_DGRAM, 0);
    if(serv_sock==-1)
        error_handling("UDP socket creation error");
    
    memset(&serv_adr, 0, sizeof(serv_adr));
    serv_adr.sin_family=AF_INET;
    serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
    serv_adr.sin_port=htons(atoi(argv[1]));
    
    if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
        error_handling("bind() error");

    while(1) 
    {
        //받는 곳

        str_len = recvfrom(serv_sock, recv_message, BUF_SIZE, 0, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
    

        if (!strcmp(recv_message, "q\n") || !strcmp(recv_message, "Q\n")) {
            sendto(serv_sock, "bye", 4, 0, (struct sockaddr*)&clnt_adr, clnt_adr_sz);
            printf("Message received from Client: %s", recv_message);
            break;
        }
        recv_message[str_len] = 0;
        printf("Message received from Client: %s", recv_message);

        
        //보내는 곳
        fputs("Insert message: ", stdout);
        fgets(send_message, sizeof(send_message), stdin);
        sendto(serv_sock, send_message, strlen(send_message), 0, (struct sockaddr*)&clnt_adr, sizeof(clnt_adr));
        
    }   
    close(serv_sock);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

sockets tcp udp
1个回答
0
投票

我相信你的问题就在这里,在服务器代码中:

socklen_t clnt_adr_sz;

[...]

while(1) 
{
    //받는 곳
    str_len = recvfrom(serv_sock, recv_message, BUF_SIZE, 0, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
    [...]

请注意,您永远不会将

clnt_adr_sz
初始化为任何值,这意味着当您稍后将指向它的指针传递给
recvfrom()
时,它的值是不确定的。由于
recvfrom()
只被授权将最多
clnt_adr_size
字节的地址数据写入
clnt_adr
,因此
clnt_adr_sz
中的值可能太小(可能为零),因此
clnt_adr
无法正确获取通过
recvfrom()
电话填写。

要修复此问题,我建议在

recvfrom()
调用之前添加此行:

clnt_adr_sz = sizeof(clnt_adr);
© www.soinside.com 2019 - 2024. All rights reserved.