1. 程式人生 > 其它 >Socket基礎六:基於資料報套接字的網路程式(udp丟包測試)

Socket基礎六:基於資料報套接字的網路程式(udp丟包測試)

技術標籤:Windows Socket網路socket

Socket基礎五:基於資料報套接字的網路程式(udp丟包測試)

作者:劉磊 2020.4.27   參考書目:《Windows網路程式設計》劉琰等著

一、功能函式

1int udp_server_fun_packetloss(SOCKET s){	
	int iResult = 0;	
	int count = 0;
	struct sockaddr_in cliaddr;	
	int addrlen = sizeof(sockaddr_in);	
	char recvline[MAXLINE];	
	do {		
		memset(
recvline, 0, MAXLINE); //接收資料 iResult = recvfrom(s, recvline, MAXLINE, 0, (SOCKADDR *)&cliaddr, &addrlen); if (iResult > 0) count++; else { int err = WSAGetLastError(); //當出現非接收超時的錯誤時列印錯誤號 if (err != 10060) { printf("recvfrom函式呼叫錯誤,錯誤號:%d\n"
, err); iResult = -1; } else { iResult = 0; break; } } } while (iResult > 0); if (count > 0) printf("伺服器總共接收到%d個數據報\n", count); return iResult; } 2int udp_client_fun_packetloss(int times, SOCKET s) { int iResult,
i = 0; char sendline[MAXLINE - 1000]; char recvtimes = 0; memset(sendline, 1, MAXLINE - 1000); //根據使用者輸入的傳送次數迴圈傳送相同的資料報 printf("\r\n客戶端傳送%d次資料\r\n", times); while (i < times) { iResult = send(s, sendline, strlen(sendline), 0); if (iResult == SOCKET_ERROR) { printf("send 函式呼叫錯誤,錯誤號:%d\n", WSAGetLastError()); return -1; } i++; //printf("\r\n客戶端傳送%d次資料\r\n", i); } return iResult; } 3int udp_client_fun_packetloss(int times, SOCKET s, SOCKADDR * servaddr, int servlen) { int iResult, i = 0; char sendline[MAXLINE - 1000]; char recvtimes = 0; memset(sendline, 1, MAXLINE - 1000); //根據使用者輸入的傳送次數迴圈傳送相同的資料報 printf("\r\n客戶端傳送%d次資料\r\n", times); while (i < times) { iResult = sendto(s, sendline, strlen(sendline), 0, (SOCKADDR *)servaddr, servlen); if (iResult == SOCKET_ERROR) { printf("send 函式呼叫錯誤,錯誤號:%d\n", WSAGetLastError()); return -1; } i++; //printf("\r\n客戶端傳送%d次資料\r\n", i); } return iResult; }

二、主函式

1、server.c 
int main(int argc, char* argv[])
{	int iResult = 0;	
	SOCKET ServerSocket; 	
	start_up(); 	
	ServerSocket = udp_server("127.0.0.1", ECHOPORT);	
	if (ServerSocket == -1)		
		return -1; 	
	int rcvbuf_len;	
	int len = sizeof(rcvbuf_len);	
	if (getsockopt(ServerSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbuf_len, &len) < 0)	
	{		
		printf("getsockopt error\n");		
		return -1;	
	}	
	printf("系統接收快取預設大小: %d\n", rcvbuf_len);	//獲得使用者輸入的系統快取大小並設定 	
	rcvbuf_len = atoi(argv[1]);	
	if (setsockopt(ServerSocket, SOL_SOCKET, SO_RCVBUF, (const char *)&rcvbuf_len, len) < 0)	
	{		
		printf("setsockopt error\n");		
		return -1;	
	}	
	printf("系統接收快取被設定為: %d\n", rcvbuf_len);	//設定套接字的接收超時時間	
	int nTimeOver = TIMEOVER;	
	if (setsockopt(ServerSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&nTimeOver, sizeof(nTimeOver)) < 0)	
	{		
		printf("setsockopt error\n");		
		return -1;	
	}	
	printf("系統接收超時時間被設定為:%d毫秒\n",nTimeOver);
	printf("伺服器準備好丟包率測試服務\n");	
	for (; ; )	
	{		
		iResult = udp_server_fun_packetloss(ServerSocket);		
		if (iResult == -1)			
		printf("當前測試出錯\n");
	}	
	quit(ServerSocket);
	return iResult; 
}    

2、Clinet.c
int main(int argc, char *argv[])
{ 	int iResult = 0;	
	SOCKET ClientSocket;	
	sockaddr_in servaddr;	
	int times; 	
	start_up(); 	
	ClientSocket = udp_client((char *)argv[1], ECHOPORT, true);	
	if (ClientSocket == -1)		
		return -1; 	
		printf("客戶端啟動成功 \n");	
	if (set_address((char *)argv[1], ECHOPORT, &servaddr, "udp") == 1)		
		return 0;	
	times = atoi(argv[2]);	
	iResult = udp_client_fun_packetloss(times,ClientSocket, (SOCKADDR *)&servaddr, sizeof(sockaddr_in));	
	if (iResult == -1)		
		printf("當前測試出錯!\n");	
		quit(ClientSocket);	return iResult; 
} 

三、結果圖

在這裡插入圖片描述