【问题标题】:Only first UDP packet sent, then connection refused仅发送第一个 UDP 数据包,然后连接被拒绝
【发布时间】:2022-11-13 01:30:46
【问题描述】:

我设法制作了一个可重现的示例(我的大型原始源代码中的所有内容都保留了下来)。问题是只发送了第一个字母a。然后,我得到send() failed: Connection refused。我不知道该怎么做,这实际上是应该工作的最小代码。

我应该说,只有当我在程序开始时打开套接字并在程序结束时关闭它时,代码才起作用。如果我为每个单独的 send() 打开一个套接字,然后立即关闭它,则不会出现错误。

#include <pcap.h>
#include <cstdio>
#include <getopt.h>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <map>
#include <vector>

#define BUFSIZE 256

#define __FAVOR_BSD

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include<netdb.h>
#include<err.h>

#include <arpa/inet.h>

#include <netinet/ether.h>

#include <netinet/ip.h>
#include <netinet/ip6.h>

#include <netinet/tcp.h>
#include <netinet/udp.h>

#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>



using namespace std;

#define BUFFER 1024                // buffer length
int sock;                        // socket descriptor

void start_connection(){
    struct sockaddr_in server, from; // address structures of the server and the client
    struct hostent *servent;         // network host entry required by gethostbyname()

    memset(&server,0,sizeof(server)); // erase the server structure
    server.sin_family = AF_INET;

    // make DNS resolution of the first parameter using gethostbyname()
    if ((servent = gethostbyname("127.0.0.1")) == NULL) // check the first parameter
        errx(1,"gethostbyname() failed\n");

    // copy the first parameter to the server.sin_addr structure
    memcpy(&server.sin_addr,servent->h_addr,servent->h_length);

    server.sin_port = htons(2055);
    if ((sock = socket(AF_INET , SOCK_DGRAM , 0)) == -1)   //create a client socket
        err(1,"socket() failed\n");

    // create a connected UDP socket
    if (connect(sock, (struct sockaddr *)&server, sizeof(server))  == -1)
        err(1, "connect() failed");
}

void send_data(char * string){
    char buffer[BUFFER];
    int msg_size,i;

    //send data to the server
    memcpy(buffer,string,2);
    msg_size=2;
    i = send(sock,buffer,msg_size,0);     // send data to the server
    if (i == -1)                   // check if data was sent correctly
        err(1,"send() failed");
    else if (i != msg_size)
        err(1,"send(): buffer written partially");
    printf("%s",string);

}


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

    //Start UDP connection
    start_connection();

    send_data("a");
    send_data("b");
    send_data("c");

    //Close the UDP connection
    close(sock);
    return 0;
}

【问题讨论】:

    标签: c++ sockets udp


    【解决方案1】:

    UDP 不提供真正可靠的连接。 connect 只是设置目标地址。 send 只会将数据放入发送缓冲区,并且只有在套接字上存在先前错误时才会失败。

    第一个send 不会失败,因为之前没有在套接字上进行任何活动,因此不会发生错误。

    但是......然后数据报被发送到目标系统。如果目标系统或中间的某些防火墙拒绝 ICMP 不可访问的数据包,则会在套接字上设置错误。然后,此错误将在套接字上的下一次系统调用时传递给应用程序 - 在本例中为第二个send

    因此,例如,如果有没有 UDP 服务器期望特定 IP 和端口上的数据包,或者如果某些防火墙明确阻止数据包.如前所述,您只会在第二个send 上收到错误消息。

    【讨论】:

    • 谢谢,这就解释了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2017-08-08
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多