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) //接收client端socket資料的執行緒
{
struct ps *p = (struct ps *)arg;
int st = p->st;
char
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
}
pthread_mutex_lock(&mutex);
status = 0;
pthread_mutex_unlock(&mutex);
pthread_cancel(*(p->thr)); //被cancel掉的執行緒內部沒有使用鎖。
return NULL;
}
void *sendsocket(void *arg) //傳送server端socket資料的執行緒
{
int st = *(int *)arg;
char s[1024];
while(1)
{
memset
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;//client端socket
// 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返回client的socket描述符
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); //關閉server端listen的socket
return EXIT_SUCCESS;
}
client端:
#define MAXBUF 131072*4
void *recvsocket(void *arg) //接收client端socket資料的執行緒
{
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) //傳送server端socket資料的執行緒
{
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); //指定一個埠號:8080,htons:將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。