在寫行程池的時候遇到了一個問題
通過客戶端下載服務端的大檔案的時候,因為服務端和客戶端網路速度不同的原因
客戶端要使用回圈recv接收大檔案.
如果不使用回圈recv,客戶端就會掛掉,這樣的話服務端因為send的一端斷開后,系統向行程發送SIGPIPE信號
結束行程
問題是:為什么客戶端會掛掉呢...網上一直找不到答案
uj5u.com熱心網友回復:
協議型別typedef struct //建立客戶端和服務端之間傳送檔案的資料結構,防止粘包
{
int trans_lenth;
char buf[1000];
}trans_t;
服務端的發送檔案代碼
#include"process_pool.h"
int trans_file(int client_fd,char* FILENAME)
{
trans_t trans;
//發送檔案名
//需要轉換成網路位元組序
trans.trans_lenth=strlen(FILENAME);
strcpy(trans.buf,FILENAME);
int ret=send(client_fd,&trans,4+trans.trans_lenth,0);
ERROR_CHECK(-1,ret,"send");
int trans_fd=open(FILENAME,O_RDONLY);
ERROR_CHECK(-1,trans_fd,"open");
//讀端斷開的話,系統會向子行程發送sigpipe信號,我們忽略它
signal(SIGPIPE,SIG_IGN);
while((trans.trans_lenth=read(trans_fd,trans.buf,sizeof(trans.buf))))
{
if(trans.trans_lenth>0)
{
ret=send(client_fd,&trans,4+trans.trans_lenth,0);
// if(-1==ret)
// {
// goto end;
// }
}else
{
send(client_fd,&trans,4+trans.trans_lenth,0);
break;
}
}
//end:
close(trans_fd);
close(client_fd);
return 0;
}
客戶端的接收檔案代碼
#include "process_pool.h"
int main(int argc,char** argv)
{
ARGS_CHECK(3,argc);
// AF_INET 表示本服務器是ipv4型別
// SOCK_STREAM表示本服務器遵循TCP協議
int socketFd=socket(AF_INET,SOCK_STREAM,0);
ERROR_CHECK(socketFd,-1,"socket");
struct sockaddr_in client_addr_info;
bzero(&client_addr_info,sizeof(client_addr_info));
client_addr_info.sin_family=AF_INET;
client_addr_info.sin_addr.s_addr=inet_addr(argv[1]);
client_addr_info.sin_port=htons(atoi(argv[2]));
int ret=connect(socketFd,(struct sockaddr*)&client_addr_info,sizeof(client_addr_info));
ERROR_CHECK(ret,-1,"connect");
int lenth;
char buf[1000]={0};
//得到服務器傳送的檔案名,buf使用前需要初始化
recv(socketFd,&lenth,sizeof(int),0);
recv(socketFd,buf,lenth,0);
int down_fd=open(buf,O_CREAT|O_WRONLY,0666);
ERROR_CHECK(-1,down_fd,"open");
while(1)
{
recv(socketFd,&lenth,sizeof(int),0);
if(0==lenth)
{
printf("下載完成\n");
break;
}else
{
recv(socketFd,buf,lenth,0);
write(down_fd,buf,lenth);
}
}
close(down_fd);
close(socketFd);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/51531.html
標籤:網絡通信
上一篇:小白對DHCP的一點理解
下一篇:小白對“路由”之淺見
