本人写一个程序,用serversocket做服务器端,对于多个clientsocket做客户端。
使用非阻塞模式通信,服务端可以发送消息、文件等对客户端进程控制。现在在进程文件传输的时候有些麻烦,请各位高手帮忙指点:(由于代码太长,只贴出部分关键地方,文件传输的地方);procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);  中的发送文件  else if State = stSend then       //发送文件
  begin
    tempText := socket.ReceiveText;  //得到发送的字符串
    if (temptext = 'next') then
    begin
      buf[0]:=$20;
      NumRead:=fileRead(opFile,buf[1],sizeof(buf)-1); //这里不断读取文件来发送;
      if NumRead < Sizeof(buf)-1 then
      begin
        State := stWait;
        FileClose(opFile);
        opFile:=-1;
      end;
      Socket.SendBuf(buf,NumRead+1);
    end
    else if TempText = 'reset' then  //得到消息停止传输文件;
    begin
      State := stWait;
      FileClose(opFile);
      opFile:=-1;
    end;
  end下面是服务端的接收文件的代码:else if State = stReceive then  // 接收文件  download
  begin
    Len := Socket.ReceiveLength;
    Socket.ReceiveBuf(buf,Len);
    //以下是接收文件的过程;
    FileWrite(opFile,buf[1],len-1);
    if Len < sizeof(buf)-1 then  //不满即是最后
    begin
      State := stWait;
      FileClose(opFile);
      opFile:=-1;
      StatusBar1.Panels.Items[1].Text := '下载文件完成!';
    end else
    begin
      for ii:=0 to ServerSocket1.Socket.ActiveConnections-1 do
      if ServerSocket1.Socket.Connections[ii].SocketHandle  = strtoint(shandle) then
      begin
      ServerSocket1.Socket.Connections[ii].SendText('next');
      break;
      end;
    end;
  end我所发送和接收文件,采用的是一问一答的发送模式,客户端在接收到服务端的消息以后,发送1024字节的文件,服务端收完这1024字节后,发送“next”命令进行下一次文件发送和接收!这种一问一答的模式在局域网是没有任何问题的,但是一拿到互联网上,就不行了。搜索了很多关于这方面的帖子,看了“哈欠”对这方面的回答比较专业,我也知道我上面的代码是没有判断Socket.SendBuf的返回值。但是希望高手能说说我这种一问一答的发送是否能行的通。是否还有其它更好的方法?

解决方案 »

  1.   

    >>但是一拿到互联网上,就不行了。
    具体怎样不行,请说清楚,是 联接不上? 发的包不全?是中间掉包?还是最后部分没收到?
    ...
    请先说明你遇到的具体问题
      

  2.   

    呵呵,不好意思。态度的确是差劲的很,在下以后会改正的。互联网发生粘包现象,但是这个是传输文件啊,粘包在传输文件过程中是没有多大防碍的,我现在又不是发送字符串,它粘就粘吧,到时候接收过来的能组合在一起不就可以了。我现在问的是,在非阻塞模式下,服务端是否可以循环接收?还是不需要循环接收每次触发Socket1Read事件即可接收到呢?
      

  3.   

    不需要循环,就在OnRead里面接。
      

  4.   

    其实你看看VCL里面的TClientSocket就知道了,它默认的也是1024的字节,服务器端使用的是异步消息的方式帮你处理的,就是只要当前缓冲区有数据等待接受就会自动触发ONREAD的事件去读取!