Socket基礎六:基於資料報套接字的網路程式(udp丟包測試)
阿新 • • 發佈:2021-02-07
Socket基礎五:基於資料報套接字的網路程式(udp丟包測試)
作者:劉磊 2020.4.27 參考書目:《Windows網路程式設計》劉琰等著
一、功能函式
1、int 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;
}
2、int 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;
}
3、int 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;
}