1. 程式人生 > >Linux:測試socket傳送和接收時,緩衝區buf的大小

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。