这里有一段代码,有两个问题不清楚,大家帮着回答,可以吗?谢谢,代码如下:
printf( "Waiting for a client to connect...\n" );
while (1) {
sck_Server_Listen = SOCKET_ERROR;
while ( sck_Server_Listen == SOCKET_ERROR ) {
sck_Server_Listen = accept( sck_Server_Listen, NULL, NULL );
}
printf( "Client Connected.\n");
sck_Server_Listen = sck_Server_Listen;
break;
}
if(( fp= fopen("c:\\XXX.rar","w")) == NULL )
{
printf("File Can Not Open To Write\n");
exit(1);
}
//从服务器接收数据到buffer中
memset(buffer,0,BUFFER_SIZE); while( length = recv(sck_Server_Listen,buffer,BUFFER_SIZE,0))
{
if(length < 0)
{
printf("Recieve Data From Server Failed!\n");
break;
}
totalrecv+=length;
write_length = fwrite(buffer,sizeof(char),length,fp); printf("write %d bytes!\n",write_length);
totalwrite+=write_length;
memset(buffer,0,BUFFER_SIZE);
}
printf("Recieve File From Server Finished\n");
printf("total receive %d\n",totalrecv);
printf("total write %d\n",totalwrite);
fclose(fp);问题1:while循环起什么作用?
2:我想把指定的文件传输到我指定的位置,是在fopen处修改,还是在fwrite处修改?如果是在fwrite处修改,怎么改?
先谢谢大家了!
printf( "Waiting for a client to connect...\n" );
while (1) {
sck_Server_Listen = SOCKET_ERROR;
while ( sck_Server_Listen == SOCKET_ERROR ) {
sck_Server_Listen = accept( sck_Server_Listen, NULL, NULL );
}
printf( "Client Connected.\n");
sck_Server_Listen = sck_Server_Listen;
break;
}
if(( fp= fopen("c:\\XXX.rar","w")) == NULL )
{
printf("File Can Not Open To Write\n");
exit(1);
}
//从服务器接收数据到buffer中
memset(buffer,0,BUFFER_SIZE); while( length = recv(sck_Server_Listen,buffer,BUFFER_SIZE,0))
{
if(length < 0)
{
printf("Recieve Data From Server Failed!\n");
break;
}
totalrecv+=length;
write_length = fwrite(buffer,sizeof(char),length,fp); printf("write %d bytes!\n",write_length);
totalwrite+=write_length;
memset(buffer,0,BUFFER_SIZE);
}
printf("Recieve File From Server Finished\n");
printf("total receive %d\n",totalrecv);
printf("total write %d\n",totalwrite);
fclose(fp);问题1:while循环起什么作用?
2:我想把指定的文件传输到我指定的位置,是在fopen处修改,还是在fwrite处修改?如果是在fwrite处修改,怎么改?
先谢谢大家了!
2.fopen()
第一个while是accept
第二个while是receive
不过这种代码看起来是挺累的,应该是异步操作才对,结果写成串行代码
也许是某个教程上的范例代码吧,仅仅只是演示功能,如果跟学者照本宣科,那是不对的
sck_click_Listen = SOCKET_ERROR;
while ( sck_click_Listen == SOCKET_ERROR ) {
sck_click_Listen = accept( sck_Server_Listen, NULL, NULL );
}
printf( "Client Connected.\n");
sck_Server_Listen = sck_click_Listen;
break;
}
它起的作用是接受客户端发送的连接请求吗?sck_Server_Listen,sck_click_Listen分别是两个进程,sck_click_Listen负责监听客户端发来的请求,传给sck_Server_Listen接受客户端连接,并一直在监听sck_click_Listen发来的请求,是这样吗?
另外2楼IamNieo说的“异步操作 ,串行代码”不太懂,可以说清楚吗?因为这个程序现在有点问题,传送的文件和原文件大小还不一致,期待大家的回答,谢谢了
1.恶补一下什么叫做进程,什么叫做线程(Socket!=进程)
2.学习一下什么叫做oop
光你提出来的问题,我倒是可以一一解答,但是你自身不提高理论基础,光这里抄一点代码,那么抄一点代码,以后会问题越来越多,写出来的东西过一段时间自己都觉得乱七八糟。
C++的代码和其他语言不太一样,不是一行代码写到尾的,你要对各个模块做可复用的封装才行。1.while(1)什么作用? 就是一个循环,有循环接收新的连接accept和循环接收新的数据recv,由于accept和recv本身是阻塞型API,以accept为例,如果没有新的连接进入,那么程序将在此一直等待,直到socket被销毁,由于你的代码while是放在主线程里面,那么就相当于程序会假死在这里,这是不对的。
2.fopen处即可打开你要写入的文件,但是对于这种网络流数据,我建议你采用ofstream来写入数据。
3.
while ( sck_click_Listen == SOCKET_ERROR ) {
sck_click_Listen = accept( sck_Server_Listen, NULL, NULL );
}
printf( "Client Connected.\n");
sck_Server_Listen = sck_click_Listen;
break;
}貌似是接收一个新的连接,但是sck_Server_Listen = sck_click_Listen,你把新的连接替换给sck_Server_Listen,何意?把主socket都杀没了,后面虽然能够工作,但是已经乱七八糟了.
4.文件大小不一致:你要自己定义一个数据包格式,格式包括数据大小、文件偏移、序列号等等。网络传输不做校验,数据是不可能100%送到远程的。
{
int command;//命令
int offset;//文件偏移
int sequence;//序列号
int len;//数据长度
};
#define CMD_TRANS_START 0x00000001//开始传输文件
#define CMD_TRANS_START_RESP 0xF0000001
#define CMD_TRANS_DATA 0x00000002//分块数据包
#define CMD_TRANS_DATA_RESP 0xF0000002
#define CMD_TRANS_STOP 0x00000003//结束传输
#define CMD_TRANS_STOP_RESP 0xF0000003
DWORD WINAPI threadRecv(LPVOID p)
{
SOCKET sock = (SOCKET)p;
packet_header header;
auto_ptr<char> buffer;
ofstream ofs;
while(true)
{
int len = recv(sock,&header,sizeof header);
if(len<=0)
break;
bufer.reset(header.len);
len = recv(sock,buffer.get(),header.len);
if(len<=0)
break;
if(header.command==CMD_TRANS_START)
{//客户端开始上传文件,首先需要把文件名传过来,服务器则根据这个请求,创建一个新文件接收
string filename;
filename.append(buffer.get(),header.len);
ofs.open(filename.c_str(),ifs:save);
//组织报文,把响应发生给客户端
packet_header resp;
memset(&resp,0x0,sizeof packet_header);
resp.command = CMD_TRANS_START_RESP;
send(sock,&resp,sizeof packet_header)
}
if(header.command==CMD_TRANS_DATA)
{//客户端分块传输数据
ofs.seek(header.offset);
ofs.write(buffer.get(),header.len);
send(...)//一样需要把CMD_TRANS_DATA_RESP反馈回去
}
if(header.command==CMD_TRANS_STOP)
{
ofs.close();
break;//应该是结束线程的时候了
}
}
shutdown(sock);
closesocket(sock);
return 0;
}
int main()
{
SOCKET sockMain = socket(...);
bind(sockMain);
listen(sockMain);
list<HANDLE> listClient;
while(true)
{
SOCKET sockClient = accept(sockMain);
if(sockClient==INVALID_SOCKET)
break;
HANDLE thd = AfxBeginThread(threadRecv,sockClient);
listClient.push_back(thd);
}
}
以上就是传统的socket编程框架。
一个连接一个线程,满足一般应用即可,但是对于网游或者IM server,上万人同时在线情况下,这种模式是不行的,因为我们可以测试一下,一个程序开启1000个线程以后,就线程堆满,不能继续启动新线程了,IOCP模式即产生
你没看清楚,他一共用了三个while