void serverStatr(int iPort)
{
WSADATA wsaData;
SOCKET m_ListenSock;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)//winsock打开
{
MessageBox(NULL,_T("开启sock错误"),_T("error"),0);
return ;
}
m_ListenSock=socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
if(m_ListenSock==INVALID_SOCKET)
{
MessageBox(NULL,_T("新建Socket失败!"),_T("ERROR"),0);
return;
}
if ( iPort <= 0 || iPort > 65535 ) {
MessageBox(NULL,_T("请输入合适的端口:1 - 65535",),_T("ERROR"),0);
goto __Error_End;
} sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = INADDR_ANY;
service.sin_port = htons(iPort); if(bind(m_ListenSock,(sockaddr*)&service,sizeof(sockaddr_in))==SOCKET_ERROR)
{
MessageBox(NULL,_T("绑定端口失败!"),_T("ERROR"),0);
goto __Error_End;
}
if(listen(m_ListenSock,5)==SOCKET_ERROR)
{
MessageBox(NULL,_T("监听失败"),_T("ERROR"),0);
goto __Error_End;
}
while(true)
{
if(SOCKET_Select(m_ListenSock,100,true))
{
sockaddr_in clientAddr;
int iLen=sizeof(sockaddr_in);
SOCKET accSock=accept(m_ListenSock,(struct sockaddr*)&clientAddr,&iLen);
if(accSock==INVALID_SOCKET)
{
continue;
}
char szBuf[1024];
FILE *pWrite;
memset(szBuf,0,sizeof(szBuf));
int iOpen=1;
pWrite=fopen("2.osg","wb+");
while(recv(accSock,szBuf,MAX_BUF_SIZE,0))
{
if(iOpen==1)
{
pWrite=fopen(szBuf,"wb+");
iOpen=0;
std::cout<<"name:"<<szBuf<<endl<<"Start";
continue;
}
if(iOpen==0)
{
if(strcmp(szBuf,"END")!=0)
{
fwrite(szBuf,1024,1,pWrite);
memset(szBuf,0,sizeof(szBuf));
}
else if(strcmp(szBuf,"END")==0)
{
fclose(pWrite);
iOpen=1;
std::cout<<"End"<<endl;
}
} }
Sleep(1000);
}
} __Error_End:
closesocket(m_ListenSock);
return;
}
上面的是服务器端的代码,用来接受从客户端传来的文件。void SendData(char* path)
{
FILE* fpRead;
fpRead=fopen(path,"rb+");
memset(szBuf,0,sizeof(szBuf));
strcpy(szBuf,path);
send(client,szBuf,sizeof(szBuf),0);
memset(szBuf,0,sizeof(szBuf));
while(!feof(fpRead))
{
fread(szBuf,1024,1,fpRead);
int isend=0;
isend=send(client,szBuf,sizeof(szBuf),0);
if(isend==SOCKET_ERROR || isend==0)
{
MessageBox(NULL,_T("发送错误"),_T("ERROR"),0);
closesocket(client);
return;
}
}
fclose(fpRead); memset(szBuf,0,sizeof(szBuf));
strcpy(szBuf,"END");std::cout<<szBuf;
send(client,szBuf,sizeof(szBuf),0);
}这个是发送数据的函数。
好像这个函数一直再发送数据,接收端接受到的数据要比发送的文件大。请问一下哪里出问题了
while(!feof(fpRead))
{
fread(szBuf,1024,1,fpRead);
int isend=0;
isend=send(client,szBuf,sizeof(szBuf),0);
if(isend==SOCKET_ERROR || isend==0)
{
MessageBox(NULL,_T("发送错误"),_T("ERROR"),0);
closesocket(client);
return;
}
}
============
这一段有问题,你应该在循环内部调用memset(szBuf,0,sizeof(szBuf));
否则,你发送的数据必然是1024的倍数。因为在读取到文件尾时,其实你的fread(szBuf,1024,1,fpRead); 语句是不能将szBuf填满的,但由于你循环内部没有将szBuf清空,所以最后一次读取时,不足的部分仍然保留了前一次的数据,自然出现大小不一致的情况。大小差应该在1024以内。
=======修改:
while(!feof(fpRead))
{
memset(szBuf,0,sizeof(szBuf));
fread(szBuf,1024,1,fpRead);
int isend=0;
isend=send(client,szBuf,sizeof(szBuf),0);
if(isend==SOCKET_ERROR || isend==0)
{
MessageBox(NULL,_T("发送错误"),_T("ERROR"),0);
closesocket(client);
return;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Connector("192.168.1.105",5000);
SendData("e:/2.osg");
Sleep(5000);
CloseConnect();
return 0;
}
如果我不closeConnect();接收端会提示无限的接收“Name”和“End”。 while(recv(accSock,szBuf,MAX_BUF_SIZE,0))
{
if(iOpen==1)
{
pWrite=fopen(szBuf,"wb+");
iOpen=0;
std::cout<<"name:"<<szBuf<<endl<<"Start";
continue;
}
if(iOpen==0)
{
if(strcmp(szBuf,"END")!=0)
{
fwrite(szBuf,1024,1,pWrite);
memset(szBuf,0,sizeof(szBuf));
}
else if(strcmp(szBuf,"END")==0)
{
fclose(pWrite);
iOpen=1;
std::cout<<"End"<<endl;
}
}
==这什么意思啊???要求szBuf正好是END么?szBuf可是个1024字节的数据啊......
name:End
StartEnd
name:End
StartEnd
name:End
StartEnd
name:End
StartEnd
name:End
StartEnd
name:End
StartEnd
name:End
一直这样循环输出
End只占了3哥字节哦,那是得取出前3个字节来比较?
End只占了3哥字节哦,那是得取出前3个字节来比较?
你的SendData函数到底怎么调用的?接收端反复收到数据,那自然是因为服务端发了才会这样。既然能收到END,说明SendData函数不是个死循环,那么就是SendData函数被死循环调用了。
可是现在当发送端退出程序后,接收端还在一直接收END。
while(recv(accSock,szBuf,MAX_BUF_SIZE,0))
{
if(iOpen==1)
{
pWrite=fopen(szBuf,"wb+");
iOpen=0;
std::cout<<"name:"<<szBuf<<endl<<"Start";
continue;
}
if(iOpen==0)
{
if(strcmp(szBuf,"END")!=0)
{
fwrite(szBuf,1024,1,pWrite);
memset(szBuf,0,sizeof(szBuf));
}
else if(strcmp(szBuf,"END")==0)
{
fclose(pWrite);
iOpen=1;
std::cout<<"End"<<endl;
}
}
你在整个循环中,你只在收到非END数据时,进行memset(szBuf,0,sizeof(szBuf))操作,而当收到END时,你没有做这个操作,导致szBuf中一直保存着END这个值。当服务端关闭时,recv函数返回的是-1,而不是你期望的0,因此while条件始终成立。就是这样。你的代码很不严谨。
谢谢鹦鹉这么耐心。我改了下代码while(true)
{
memset(szBuf,0,sizeof(szBuf));
int iRet=recv(accSock,szBuf,MAX_BUF_SIZE,0);
if(iRet>0)
{
if(iOpen==1)
{
pWrite=fopen(szBuf,"wb+");
iOpen=0;
std::cout<<"name:"<<szBuf<<endl<<"Start";
continue;
}
if(iOpen==0)
{
if(strcmp(szBuf,"END")!=0)
{
fwrite(szBuf,1024,1,pWrite);
}
else if(strcmp(szBuf,"END")==0)
{
fclose(pWrite);
iOpen=1;
std::cout<<"End"<<endl;
}
}
}
else
{
closesocket(m_ListenSock);
break;
} }
为什么在一台机器上运行没问题。在局域网中,接收到的文件就有问题。。
if(iOpen==0)
{
if(strcmp(szBuf,"END")!=0)
{
fwrite(szBuf,1024,1,pWrite);
}
else if(strcmp(szBuf,"END")==0)
{
fclose(pWrite);
iOpen=1;
std::cout<<"End"<<endl;
}
}
其实是有问题的,fwrite(szBuf,1024,1,pWrite);是不合理的。你怎么肯定每次都是1024呢?文件的最后一部分谁能保证正好1024呢?你应该用iRet替代1024,iRet才代表实际收到的字节数。
int isend=0;
isend=send(client,szBuf,sizeof(szBuf),0);
改为 int iRed=fread(szBuf,1,1024,fpRead);
int isend=0;
isend=send(client,szBuf,iRed,0);基础不扎实啊。而且好多时候总是按照自己的想法来。
谢谢鹦鹉兄一直耐心的帮助我。谢谢