我设法制作了一个可重现的示例(保留了我的大型原始源代码中的所有内容)。问题是只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)
UDP不提供真正可靠的连接。connect只需设置目标地址。Asend只会将数据放入发送缓冲区,并且只有在套接字上存在先前错误时才会失败。
第一个send不会失败,因为之前没有在套接字上执行任何活动,因此不会发生错误。
但是......数据报随后被发送到目标系统。如果目标系统或中间的某些防火墙拒绝 ICMP 无法到达的数据包,则将在套接字上设置错误。然后,该错误将在套接字上的下一个系统调用(本例中是第二个)上传递给应用程序send。
因此,如果没有UDP 服务器期望特定 IP 和端口上的数据包,或者如果某些防火墙明确阻止数据包,则您观察到的情况将会发生。正如所解释的,您仅在第二个时收到错误send。
| 归档时间: |
|
| 查看次数: |
155 次 |
| 最近记录: |