Linux下的通信时延测试程序

jeason 2015-03-25

今天段老师在网络软件设计课上布置了一个题目。

要求是Windows环境,现在在Linux环境下实现。

运行C/S模式的2个程序,使用UDP协议,发送10次,计算平均时延。

服务器程序如下:

#include <sys/socket.h> // for functions for socket
#include <netinet/in.h> // for struct sockaddr_in
#include <stdlib.h>
#include <memory.h> // for memset
#include <stdio.h> // for perror
#include <errno.h> // for errno

#define BUFLEN 100
int main(void)
{
    int listenfd;
    char buf[BUFLEN];
    socklen_t len;
    struct sockaddr_in serv, cli;

    if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    { // use udp
        perror("socket");
        exit(EXIT_FAILURE);
    }

    memset(&serv, 0, sizeof(serv)); // clear
    serv.sin_family = AF_INET; // use IPv4
    // Listen any ip address and use network
    // byte order
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    serv.sin_port = htons(9877); // Listen port 9877

    if (bind(listenfd, (struct sockaddr*)&serv, sizeof(serv)) < 0)
    { // bind the socket to the server address
        perror("bind");
        exit(EXIT_FAILURE);
    }

    for ( ; ; )
    {
        len = sizeof(cli);
        if ((recvfrom(listenfd, buf, BUFLEN, 0,
                (struct sockaddr*)&cli, &len)) < 0)
        {  // recvfrom the listenfd
            // put the message into buf
            // no flags (4th argument 0)
            // save the client address and length
            if (errno == EINTR || errno == EAGAIN)
                continue;
            perror("recvfrom");
            exit(EXIT_FAILURE);
        }
        if ((sendto(listenfd, "Got it!", 10, 0,
                (struct sockaddr*)&cli, len)) < 0)
        {  // send the message back
            // send message "Got it!" back
            if (errno == EINTR || errno == EAGAIN)
                continue;
            perror("sendto");
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}

客户端程序如下:

#include <sys/socket.h> // for functions for socket
#include <arpa/inet.h> // for inet_pton
#include <netinet/in.h> // for struct sockaddr_in
#include <stdlib.h>
#include <memory.h> // for memset
#include <stdio.h> // for perror
#include <errno.h> // for errno
#include <time.h>

#define SENDTIMES 10
#define BUFLEN 100
int main(int argc, char* argv[])
{
    struct sockaddr_in serv;
    int sockfd;
    int i;
    clock_t start, finish;
    double duration, total = 0;
    char buf[BUFLEN];

    if (argc != 2)
    {
        fprintf(stderr, "Usage: ./udpcli <IPADDR>\n");
        exit(EXIT_FAILURE);
    }

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    { // use udp
        perror("socket");
        exit(EXIT_FAILURE);
    }

    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_port = htons(9877);
    if ((inet_pton(AF_INET, argv[1],
        &serv.sin_addr)) == 0)
    { // read the string to the structrue
        perror("inet_pton");
        exit(EXIT_FAILURE);
    }

again:
    if ((connect(sockfd,
            (struct sockaddr*)&serv, sizeof(serv))) < 0)
    { // this connect is for catch the
      // error ICMP packets
        if (errno == EINTR || errno == EAGAIN)
            goto again;
        perror("connect");
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < SENDTIMES; ++i)
    {
        printf("Send %d messages.\n", i + 1);
        start = clock();
again2:
        if ((sendto(sockfd, "A message!", 20, 0,
            (struct sockaddr*)&serv, sizeof(serv))) < 0)
        {
            if (errno == EINTR)
                goto again2;
            perror("sendto");
            exit(EXIT_FAILURE);
        }
again3:
        if ((recvfrom(sockfd, buf, BUFLEN, 0,
            NULL, NULL)) < 0)
        {
            if (errno == EINTR)
                goto again3;
            perror("recvfrom");
            exit(EXIT_FAILURE);
        }
        finish = clock();
        duration = finish - start;
        printf("Spend time: %fms\n", duration / CLOCKS_PER_SEC * 1000);
        total += duration;
    }

    printf("\nAverage time: %fms\n", total / SENDTIMES / CLOCKS_PER_SEC * 1000);
    return 0;
}

相关推荐