int length=file.GetLength();
byte* data=new byte[length];
file.Read(data,length);
for(pos=m_SocketList.GetHeadPosition();pos!=NULL;)
{
     pSocket=(CClientSocket*)m_SocketList.GetNext(pos);
pSocket->Send(&length,4);//此处的4是什么意思?限定了length的字节数小于4么?
pSocket->Send(data,length);
}
这样只能实现传送文本文件,是不是因为字节数的原因呢?如果要实现传输更大一点的文件,如音乐,该怎么办呢???

解决方案 »

  1.   

    没必要先传一个大小过去,4是sizeof(int)的意思吧。TCP传输数据可以可以一次发一个大的。对方接收时使用while循环来接我做的工作是一段一段发送的,对方一段一段接收,测试时用的是20M左右的文件。下面的代码是随手写的,用在接收端吧。之前用select检查一下,免得超时。
    具体看MSDN吧BYTE buffer[1024];
    memset(buffer, 0, sizeof(buffer));
    while(true)
    {
      int nSize =  mySocket.Recive(buffer, sizeof(buffer))
      if(nSize == SOCKET_ERROR)
    {
    //出错了
    }
      else if(nSize < sizeof(buffer))
    {
    //收完了
    }
    else
    {
    //先把buffer里的东西存起来再说
    }
    }
      

  2.   

    加上一点:
    while循环要在合适的地方break的说
      

  3.   

    File Transfer Using CSockets:
    http://www.codeguru.com/network/FileTransferUsingSockets.shtml
      

  4.   

    那个4是sizoef(int),即length的长度。
    socket是流式的,只有连接(起点)和关闭(终点),每次发送的字节数和每次接收的字节数并不一致。所以有必要在发送数据之前先发送一个要发送数据的长度,接收时先读出数据长度,然后接收该长度的数据。
    要发送大的文件:
    int length=file.GetLength();
    BYTE buffer[1024];
    for(pos=m_SocketList.GetHeadPosition();pos!=NULL;)
    {
      pSocket=(CClientSocket*)m_SocketList.GetNext(pos);
       pSocket->Send(&length,sizeof(int));
       int cbw = 0;
       while(cbw < length)
       {
          int len = sizeof(buffer);
          if (len > length-cbw)
              len = length-cbw;
          len = (int)file.Read(buffer,len);
          pSocket->Send(buffer,len);
          cbw += len;
       }
    }
      

  5.   

    以上的方法是可行的,当如果我们仔细看一下MFC对于CSocket::Send方法所做的封装(在sockcore.cpp中),会发现没有必要向上面提到的一次只发送一个1024的buffer,而是可以直接分配文件长度大小的内存并使用send发送,如下:
    byte* data = new byte[myFileLength]; 
    myFile.Read(data, myFileLength);
    sockRecv.Send(data, myFileLength); 
    以下是MFC封装代码:
    int CSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
    {
    if (m_pbBlocking != NULL)
    {
    WSASetLastError(WSAEINPROGRESS);
    return  FALSE;
    } int nLeft, nWritten;
    PBYTE pBuf = (PBYTE)lpBuf;
    nLeft = nBufLen; while (nLeft > 0)
    {
    nWritten = SendChunk(pBuf, nLeft, nFlags);
    if (nWritten == SOCKET_ERROR)
    return nWritten; nLeft -= nWritten;
    pBuf += nWritten;
    }
    return nBufLen - nLeft;
    }int CSocket::SendChunk(const void* lpBuf, int nBufLen, int nFlags)
    {
    int nResult;
    while ((nResult = CAsyncSocket::Send(lpBuf, nBufLen, nFlags)) == SOCKET_ERROR)
    {
    if (GetLastError() == WSAEWOULDBLOCK)
    {
    if (!PumpMessages(FD_WRITE))
    return SOCKET_ERROR;
    }
    else
    return SOCKET_ERROR;
    }
    return nResult;
    }
    int CAsyncSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
    {
    return send(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
    }
    可以看到,CAsyncSocket是直接调用了API send方法,是一层薄得不能再薄的封装,而对于CSocket 则做了更多的处理,只用全部发送出去才会返回。
    所以,如果使用CAsyncSocket::send就要使用while循环,但我不赞成使用固定大小buffer发送,而是要使用如上面封装时的算法发送。(更多可以参考《windows网络编程》)
    当然,如果文件过大,以至于超过heap所允许的范围,是要分很多次的,但我们至少要搞清楚为什么要分很多次。
      

  6.   

    页面
    http://www.vckbase.com/code/listcode.asp?mclsid=9&sclsid=901
    下载地址
    http://www.vckbase.com/code/downcode.asp?id=1511