这里有一段代码,有两个问题不清楚,大家帮着回答,可以吗?谢谢,代码如下:
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处修改,怎么改?
先谢谢大家了!

解决方案 »

  1.   

    1.不清楚你说哪个while(),反正有一个是多余的.
    2.fopen()
      

  2.   

    多余倒是没有多余
    第一个while是accept
    第二个while是receive
    不过这种代码看起来是挺累的,应该是异步操作才对,结果写成串行代码
    也许是某个教程上的范例代码吧,仅仅只是演示功能,如果跟学者照本宣科,那是不对的
      

  3.   

    我指的是第一个while。不过我代码输入有误,不好意思了。应该为while (1) { 
            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说的“异步操作 ,串行代码”不太懂,可以说清楚吗?因为这个程序现在有点问题,传送的文件和原文件大小还不一致,期待大家的回答,谢谢了
      

  4.   

    建议:
    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%送到远程的。
      

  5.   

    对于socket server来说,重要的事情是2个,accept和recv,这2个事情是不能放在一个线程里面跑的(对于高级的服务器编程IOCP除外)大概给你写了一下框架,struct packet_header
    {
      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模式即产生
      

  6.   

    谢谢楼上这位IamNieo朋友,你很热心。我看的一知半解,不好意思,现在水平有限。我用的是c,貌似C好像不能用ofstream来编程序吧。我后面在好好查漏补习,谢谢您
      

  7.   


    你没看清楚,他一共用了三个while