UDP的ICMP差错的测试程序

阅读更多
/*
作者:张亚霏
2008-12-03早
*/

/*
UDP主机不可达、端口不可达测试
*/

/*
向一个已知主机的打开端口发一个UDP包,无任何异常
*/

/*
向一个已知主机的未打开端口发一个UDP包
主机返回一个ICMP端口不可达报文
结果就是之后的recvfrom返回-1
GetLastError() WSAECONNRESET
or
errno ECONNRESET
*/

/*
向一个未知主机的某端口发一个UDP包
可能无任何回应
也可能是中间路由器返回一个ICMP主机不可达报文,但是这种情况很少见
结果就是之后的recvfrom返回-1
GetLastError() WSAEHOSTUNREACH
or
errno EHOSTUNREACH
*/


#if defined WIN32 || defined _WIN32


#include 
#include 
#pragma comment(lib, "ws2_32.lib")

int init_net()
{
	WSADATA wsa_data;
	return 0 != WSAStartup(MAKEWORD(2,2), &wsa_data);
}

void uninit_net()
{
	WSACleanup();
}

int close_socket(SOCKET s)
{
	return closesocket(s);
}

int get_last_error()
{
	return WSAGetLastError();
}
#else

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int init_net()
{
	return 1;
}

void uninit_net()
{
}


typedef int SOCKET;

int close_socket(SOCKET s)
{
	return close(s);
}

int get_last_error()
{
	return errno;
}
#endif



#define BUFFER_SIZE 1024
#define DEST_ADDRESS "127.0.0.1"//"192.168.1.2"
#define DEST_PORT 27015//1037


int main()
{
	
	SOCKET send_socket;
	struct sockaddr_in recv_addr;
	char send_buf[BUFFER_SIZE];
	char recv_buf[BUFFER_SIZE];
	int ret;

	fd_set read_set;
	struct timeval time_out;

	init_net();

	send_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	recv_addr.sin_family = AF_INET;
	recv_addr.sin_port = htons(DEST_PORT);
	recv_addr.sin_addr.s_addr = inet_addr(DEST_ADDRESS);



	ret = sendto(send_socket, 
		send_buf, 
		BUFFER_SIZE, 
		0, 
		(struct sockaddr*) &recv_addr, 
		sizeof(recv_addr));

	FD_ZERO(&read_set);
	FD_SET(send_socket, &read_set);
	time_out.tv_sec = 1;
	time_out.tv_usec = 0;
	
	ret = select(send_socket+1, &read_set, NULL, NULL, &time_out);
	if(ret == 1 && FD_ISSET(send_socket, &read_set))
	{
		ret = recvfrom(send_socket, recv_buf, BUFFER_SIZE, 0, NULL, NULL);
		if(ret == -1)
		{
			printf("get_last_error() %d\n", get_last_error());
			perror(NULL);
		}
	}

	close_socket(send_socket);
	uninit_net();
	return 0;
}

你可能感兴趣的:(Socket,.net,C,C++,C#)