仅发送第一个 UDP 数据包,然后连接被拒绝

amp*_*der 0 c++ sockets udp

我设法制作了一个可重现的示例(保留了我的大型原始源代码中的所有内容)。问题是只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;
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ich 7

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

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

但是......数据报随后被发送到目标系统。如果目标系统或中间的某些防火墙拒绝 ICMP 无法到达的数据包,则将在套接字上设置错误。然后,该错误将在套接字上的下一个系统调用(本例中是第二个)上传递给应用程序send

因此,如果没有UDP 服务器期望特定 IP 和端口上的数据包,或者如果某些防火墙明确阻止数据包,则您观察到的情况将会发生。正如所解释的,您仅在第二个时收到错误send