c UDP statistics packet loss in network programming

Introduction

This project is completed between two hosts under the LAN. It requires one host to continuously send 100 packets to the other host, and count the number of packets actually received by the other host.

programming

1. Configuration environment The
experiment is developed in Dev C++. Because of the use of the relevant APIs of windows network programming, it is necessary to include the <winsock2.h> header file and add the static link file wsock32.lib to the project.
The method of adding static link files: project -> project properties -> parameters -> link -> add library or object, find wsock32.lib and add it to the project.
Choose two hosts under the same LAN as the sender and receiver respectively, with ip as 192.168.1.109 and 192.168.1.108 respectively.

2. Program design
Create a new project on the sender host, import the required header files and static link files, and then write the sender program;
create a new project on the receiver host, import the required header files and static link files, Then write the receiving end program.
The sender program is roughly divided into the following parts:
use socket() to create a socket serverscok, use bind() to bind the host's ip and a port for the socket, create a struct sockaddr_in object and set the receiver's ip and port number Assign to it, use sendto() to send 100 UDP data packets from serversock to the receiving end in a loop, and use closesocket() to release the resources allocated to the socket.
The receiving end program is roughly divided into the following parts:
use socket() to create a socket clientsock, use bind() to bind the host's ip and a port for the socket, and use recvfrom() to receive the sender in a loop For incoming packets, count the number of lost packets, and use closesocket() to release the resources allocated to the socket.

Program realization

Sender

//server which send messages to client

#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#define WSVERS MAKEWORD(2, 0)
void errexit(const char*, ...);//错误信息打印函数

int main(int argc, char* argv[]) {
    
    
    struct sockaddr_in sock_address, to_address;
    SOCKET serversock;
    WSADATA wsadata;
    
    if (WSAStartup(WSVERS, &wsadata) != 0) {
    
    
        errexit("WSAStartup failed\n");
    }
    //create and bind serversock
    serversock = socket(AF_INET, SOCK_DGRAM, 0); //获得serversock
    sock_address.sin_family = AF_INET; //设置地址家族
    sock_address.sin_port = htons(12345); //设置端口
    sock_address.sin_addr.s_addr = inet_addr("192.168.1.109"); //设置地址
    int flag = bind(serversock, (struct sockaddr*) &sock_address, sizeof(struct sockaddr));
    if (flag != 0) errexit("bind falied.\n");

    char buf[4096];
    
    //initiate to_address with client's address
    to_address.sin_family = AF_INET;
    to_address.sin_port = htons(12345); //设置端口
    const char * addr = "192.168.1.108";
    to_address.sin_addr.s_addr = inet_addr(addr); //设置地址
     
    int count = 0;
    while (++count <= 101) {
    
    
        char buf[4096];
        if (count <= 100)
            sprintf(buf, "Hello, I'm number %d of packet sent from %s", count, "192.168.1.109");
        else 
            sprintf(buf, "end of messages");
        flag = sendto(serversock, buf, 4096, 0, (struct sockaddr*) &to_address, sizeof(struct sockaddr));
        if (flag == -1) {
    
    
            errexit("send falied, errno = %d\n", GetLastError());
        }
        printf("send message '%s' to %s\n", buf, addr);
    }
    
    (void)closesocket(serversock);

    return 0;
    
}


void errexit(const char *format, ...) {
    
    
    va_list args;

    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    WSACleanup();
    exit(1);

}

Receiving end

//client which receive messages from server

#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#define WSVERS MAKEWORD(2, 0)
void errexit(const char*, ...);//错误信息打印函数

int main(int argc, char* argv[]) {
    
    
    struct sockaddr_in sock_address, from_address;
    SOCKET clientsock;
    WSADATA wsadata;
    
    if (WSAStartup(WSVERS, &wsadata) != 0) {
    
    
        errexit("WSAStartup failed\n");
    }
    //create and bind serversock
    clientsock = socket(AF_INET, SOCK_DGRAM, 0); //获得serversock
    sock_address.sin_family = AF_INET; //设置地址家族
    sock_address.sin_port = htons(12345); //设置端口
    sock_address.sin_addr.s_addr = inet_addr("192.168.1.108"); //设置地址
    int flag = bind(clientsock, (struct sockaddr*) &sock_address, sizeof(struct sockaddr));
    if (flag != 0) errexit("bind falied.\n");

    
     
    char buf[4096];
    
    int count = 0;
    int fromlen;
    const char* endquotes = "end of messages";
    while (true) {
    
    
        flag = recvfrom(clientsock, buf, 4096, 0, NULL, NULL);
        if (flag == -1) {
    
    
            errexit("receive falied, errno = %d\n", GetLastError());
        }
        printf("%s\n", buf);
        if (strcmp(endquotes, buf) == 0) break;
        ++count;
        printf("count: %d\n", count);
    }
    printf("\n\ntotal 100, actually receive %d, lost %d\n", count, 100 - count);
    (void)closesocket(clientsock);

    return 0;
    
}

void errexit(const char *format, ...) {
    
    
    va_list args;

    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    WSACleanup();
    exit(1);

}

operation result

Run the receiver program first, make it in a blocking state, and then run the sender program.
The results show that the sender successfully sent 101 UDP data packets (including the last data packet to indicate the end of the transmission). The
Insert picture description here
receiver successfully received 71 packets out of 100 packets and lost 29 packets.
Insert picture description here
Insert picture description here

to sum up

The program still has a little flaw. If the packet itself as the end information is lost, the receiving end will wait until the end information is received, but it does not affect the overall situation (the big deal will be repeated), so I will not change it.

Guess you like

Origin blog.csdn.net/weixin_43867940/article/details/106414102