Linux:测试socket发送和接收时,缓冲区buf的大小

可通过以下程序测试socket发送和接收时,缓冲区buf的大小:

server端:

struct ps{

    int st;

    pthread_t *thr;

};

 

#define MAXBUF 131072

 

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

 

int status = 0;

 

void *recvsocket(void *arg) //接收clientsocket数据的线程

{

    struct ps *p = (struct ps *)arg;

    int st = p->st;

    char s[1024];

    char *pp = malloc(MAXBUF);

    while(1)

    {

       char buf[100];

       read(STDIN_FILENO, buf, sizeof(buf));

       memset(s, 0, sizeof(s));

       int rc = recv(st, pp, MAXBUF, 0);

       printf("rc =%d\n", rc);

       if(rc <= 0) //如果返回小于等于0,代表socket已经关闭或者出错

           break;

    //  printf("%s\n",s);

    }

    pthread_mutex_lock(&mutex);

    status = 0;

    pthread_mutex_unlock(&mutex);

    pthread_cancel(*(p->thr)); //cancel掉的线程内部没有使用锁。

    return NULL;

}

 

void *sendsocket(void *arg) //发送serversocket数据的线程

{

    int st = *(int *)arg;

    char s[1024];

 

    while(1)

    {

       memset(s, 0, sizeof(s));

       read(STDIN_FILENO, s, sizeof(s)); //从键盘读取用户输入信息

       send(st, s, strlen(s), 0);

    }

    return NULL;

}

 

int main(int arg, char *args[])

{

    if(arg < 2)

    {

       return -1;

    }

    int port = atoi(args[1]);

    int st = socket(AF_INET, SOCK_STREAM, 0); //初始化socket

    int on = 1;

    if(setsockopt(st, SOL_SOCKET, SO_REUSEADDR,&on, sizeof(on)) == -1)

    {

       printf("setsockoptfailed %s\n", strerror(errno));

       return EXIT_FAILURE;

    }

    struct sockaddr_in addr; //定义一个IP地址的结构

    memset(&addr, 0, sizeof(addr));

    addr.sin_family = AF_INET; //设置addr结构的属性定位为TCP/IP地址

    addr.sin_port = htons(port); //将本地字节顺序转化为网络字节数据

    addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY代表这个server上所有的地址

    //IP地址与server程序绑定

    if(bind(st, (struct sockaddr *)&addr, sizeof(addr)) == -1)

    {

       printf("connectfailed %s\n", strerror(errno));

       return EXIT_FAILURE;

    }

    //server端开始listen

    if(listen(st, 20) == -1)

    {

       printf("listenfailed %s\n", strerror(errno));

       return EXIT_FAILURE;

    }

    int client_st = 0;//clientsocket

//  socklen_t len = 0;

    struct sockaddr_in client_addr; //表示client端的IP地址

    //void *p = &client_addr;

 

    pthread_t thrd1, thrd2;

    while(1)

    {

       memset(&client_addr, 0, sizeof(client_addr));

       socklen_t len = sizeof(client_addr);

       //accept会阻塞,直到有客户端连接过来,accept返回clientsocket描述符

       client_st = accept(st, (struct sockaddr *)&client_addr,&len);

       pthread_mutex_lock(&mutex); //为全局变量加一个互斥锁,防止与线程函数同时读写变量的冲突

       status++;

       pthread_mutex_unlock(&mutex); //解锁

       if(status > 1) //代表这是第二个socket连接,关闭(确保只能连接一个socket

       {

           close(client_st);

           continue;

       }

       if(client_st == -1)

       {

           printf("acceptfailed %s\n", strerror(errno));

           return EXIT_FAILURE;

       }

       printf("accept by%s\n", inet_ntoa(client_addr.sin_addr));

       struct ps ps1;

       ps1.st = client_st;

       ps1.thr = &thrd2;

       pthread_create(&thrd1, NULL, recvsocket, &ps1);

       pthread_detach(thrd1); //设置线程为可分离

//     pthread_create(&thrd2, NULL, sendsocket, &client_st);

//     pthread_detach(thrd2); //设置线程为可分离

    }

    close(st); //关闭serverlistensocket

    return EXIT_SUCCESS;

}

 

client端:

#define MAXBUF 131072*4

 

void *recvsocket(void *arg) //接收clientsocket数据的线程

{

    int st = *(int *)arg;

    char s[1024];

 

    while(1)

    {

       memset(s, 0, sizeof(s));

       int rc = recv(st, s, sizeof(s), 0);

       if(rc <= 0) //如果返回小于等于0,代表socket已经关闭或者出错

       {

           break;

       }

       printf("%s\n", s);

    }

    return NULL;

}

 

void *sendsocket(void *arg) //发送serversocket数据的线程

{

    int st = *(int *)arg;

    char s[1024];

    char *p = malloc(MAXBUF); //

    while(1)

    {

       memset(s, 0, sizeof(s));

       read(STDIN_FILENO, s, sizeof(s)); //从键盘读取用户输入信息

       int rc = send(st, p, MAXBUF, 0);

       printf("rc =%d\n", rc);

    }

    return NULL;

}

 

int main(int arg, char *args[])

{

    if(arg < 3)

       return -1;

    int port = atoi(args[2]);

    int st = socket(AF_INET, SOCK_STREAM, 0); //初始化socket

    struct sockaddr_in addr; //定义一个IP地址的结构

    memset(&addr, 0, sizeof(addr));

    addr.sin_family = AF_INET; //设置结构地址类型为TCP/IP地址

    addr.sin_port = htons(port); //指定一个端口号:8080htons:short类型从host字节类型到net字节类型转化

    addr.sin_addr.s_addr = inet_addr(args[1]); //将字符串类型的IP地址转化为int,赋给addr结构

    //调用connect连接到结构addr指定的IP地址和端口号

    if(connect(st, (struct sockaddr *)&addr, sizeof(addr)) == -1)

    {

       printf("connectfailed %s\n", strerror(errno));

       return EXIT_FAILURE;

    }

 

    pthread_t thrd1, thrd2;

    pthread_create(&thrd1, NULL, recvsocket, &st);

    pthread_create(&thrd2, NULL, sendsocket, &st);

    pthread_join(thrd1, NULL);

    //pthread_join(thrd2, NULL);

 

    close(st); //关闭socket

    return EXIT_SUCCESS;

}

运行结果如下:


一次发送了521k的数据,服务器端分4次接收(服务端程序中设置的是每按下回车键一次,接收一次数据)。

经测试,centos64系统的接收端的缓冲区大小是128k。


猜你喜欢

转载自blog.csdn.net/zangyongcan/article/details/52139116
今日推荐