做一个基于TCP的文件传输程序:
发送端如下:
SOCKET sockConn=accept(FileSock.FileSocket,(SOCKADDR*)&addrfrom,&length);
do
{
dwRead=sourceFile.Read(sendBuf,10240);
send(sockConn,sendBuf,dwRead,0);
}
while(dwRead>0);
closesocket(sockConn);
sourceFile.Close();//----------
接收端如下:
char recvBuf[10240];//strlen(recvBuf)
WORD FileByte;
while(m_FileLength > 0)//m_FileLength为接收文件的长度
{
  FileByte=recv(FileSock.sockClient,recvBuf,sizeof(recvBuf),0);
  destFile.Write(recvBuf,10240);
  m_FileLength-=FileByte;
}
destFile.Close();
AfxMessageBox("文件接收完成!",MB_OK,IDS_Msg);
return 0;其中,接收端和发送端所用的套节字在一个类中做的初始化!
基初始化函数如下:
BOOL CFileSocket::InitSocket()//文件发送端
{
FileSocket=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrsock;
addrsock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrsock.sin_family=AF_INET;
addrsock.sin_port=htons(8413); bind(FileSocket,(SOCKADDR*)&addrsock,sizeof(SOCKADDR)); listen(FileSocket,10); return TRUE;
}
//---BOOL CFileSocket::InitClientSock(CString SrvIP)//接收端
{
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr(SrvIP);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(8413);

connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
return 1;
}
   现在,程序运行时,接收端不停的接收数据,就算我把发送端的send函数屏蔽掉,它同样也在不停的接收数据,而接收到的数据都是乱码。
发送端也一样,不停的往外发送数据,就算我把客户的recv函数屏蔽掉,那也同样不停的发送数据。也不知道到里是不是发送到客户端去了。按道理,基于TCP的SOCKED编程应该是在阻塞下执行的,也就是服务器端的send函数要把数据发送成功才进行返回,可是这里也没有看到这种情况!
   希望高手们帮忙看看,到里程序错在那里,我查了半天也没有找出问题来。

解决方案 »

  1.   

    发送和接收成功后返回,失败后也会立即返回的,例如在通讯断开的情况下,所以你应该检测发送和接收操作是否成功,如果不成功则中断操作,再者,你一次发送10k,不一定能一次发送出去,所以也因该检测实际的发送数,接收也是如此:例如
    int rc1, nSend;
    do
    {
    dwRead=sourceFile.Read(sendBuf,10240);
    nSend = 0;
    do
    {
    rc = send(sockConn,sendBuf+nSend,dwRead,0);
    nSend += rc;
    }while(rc != SOCKET_ERROR && nSend < dwRead)
    if(rc == SOCKET_ERROR)//发送错误
    break;
    }
    。。
    while(m_FileLength > 0)//m_FileLength为接收文件的长度
    {
      FileByte=recv(FileSock.sockClient,recvBuf,sizeof(recvBuf),0);
      if(FileByte == SOCKET_ERROR)//接收错误
          break;
      destFile.Write(recvBuf,FileByte); //这儿应该是实际接收的长度
      m_FileLength-=FileByte;
    }
      

  2.   

    谢谢 zottff() ( ) 信誉:100 
    。。
    你提到的这些我还真没有考虑到,我改改再试试看能不能成功!
      

  3.   

    现在,程序运行时,接收端不停的接收数据,就算我把发送端的send函数屏蔽掉,它同样也在不停的接收数据,而接收到的数据都是乱码。
    发送端也一样,不停的往外发送数据,就算我把客户的recv函数屏蔽掉,那也同样不停的发送数据。也不知道到里是不是发送到客户端去了。按道理,基于TCP的SOCKED编程应该是在阻塞下执行的,也就是服务器端的send函数要把数据发送成功才进行返回,可是这里也没有看到这种情况!
       希望高手们帮忙看看,到里程序错在那里,我查了半天也没有找出问题来。
    ____________________________________________________________________根据你说的现在象,有可能是你服务器的侦听SOCKET有问题,你断点调试一下,看看在SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);这里有没有阻塞住
      

  4.   

    zottff() 
    //------------------
    int rc1, nSend;
    do
    {
    dwRead=sourceFile.Read(sendBuf,10240);
    nSend = 0;
    do
    {
    rc = send(sockConn,sendBuf+nSend,dwRead,0);
    nSend += rc;
    }while(rc != SOCKET_ERROR && nSend < dwRead)
    if(rc == SOCKET_ERROR)//发送错误
    break;
    }你这段代码看不懂啊!
    里面怎么会有两个Do呢?
      

  5.   

    这是一个双重循环啊,第一层循环是读文件的,第二层是将读出来的数据循环发送的,最后少了一个while条件
    int rc, nSend;
    do
    {
    dwRead=sourceFile.Read(sendBuf,10240);
    nSend = 0;
    do
    {
    rc = send(sockConn,sendBuf+nSend,dwRead,0);
    nSend += rc;
    }while(rc != SOCKET_ERROR && nSend < dwRead)
    if(rc == SOCKET_ERROR)//发送错误
    break;
    }while(dwRead>0);
      

  6.   

    呵,我刚正看出了后面那个While语句了。
    send(sockConn,sendBuf+nSend,dwRead,0);
    该函数对第二个参数书上是这样说的:将要被传送的数据。难道这个被传送的数据不是在这一次send中完成的吗?而dwRead这是指第二个参数中的数据长度!还有这个send的返回值,它是不是返回实际发送的字节数呢?再问一下:sendBuf+nSend这个表示是不是指针后移呢?
    还有,我对这个while(rc != SOCKET_ERROR && nSend < dwRead)条件不太明白!
    rc不等于SOCKET_ERROR 并且nSend < dwRead
    接着再进入while语句?
      

  7.   

    还有我问一下:
    send和recv函数都应该是阻塞执行的嘛,就拿recv来说,如果它没有等到要接收的数据到来的话应该是阻塞等待的嘛,及到对方发送数据过来,它才可以接收数据返回,程序才得以向下执行。
    所以我想问一下zottff()你说:发送和接收成功后返回,失败后也会立即返回的……
    你这里的接收失败应该怎么样理解呢?是不是指recv函数在对方没有数据发送过来的情况下,recv函数也会返回,而不阻塞进行等待对方send数据过来呢?
      

  8.   

    第一个问题:数据太长的话一次不能完全发送出去,如果发送成功send返回返回实际发送字节数,次数可能小于你要发送的节数第2个问题:sendBuf+nSend是表示指针后移
    while(rc != SOCKET_ERROR && nSend < dwRead)的意思是发送不出错,并且已发送字节数小于从文件中读出来的要发送的字节数,如果条件成立就继续循环发送