请大家帮我看一个socket传文件丢失信息的问题。
初学socket,很多地方都不懂。
昨天写了个程序,传文件的时候发送接收都在本机没有问题,放在局域网传,文件就
接收的不完整了,怎么想不通,希望大家能给点指点!!
代码如下
发送端:
#include <Winsock2.h>
#include <stdio.h>
//连接一个库文件project-> setting-> link:object/library modules添加:ws2_32.lib
void main()
{
WORD wVersionRequested;//版本号
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//1.1版本的套接字
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}//加载套接字库,加裁失败则返回
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}//如果不是1.1的则退出
SOCKET sockServer = socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrServer;
addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrServer.sin_family=AF_INET;
addrServer.sin_port=htons(6000);
bind(sockServer,(SOCKADDR *)&addrServer,sizeof(SOCKADDR));//绑定
listen(sockServer,5);//监听
SOCKADDR_IN sockClient;
int IClientSockLen=sizeof(SOCKADDR);
while(1){
SOCKET sockConn;
sockConn=accept(sockServer,(SOCKADDR *)&sockClient,&IClientSockLen);
FILE *fp;
if((fp=fopen( "111.exe ", "rb "))==NULL)//打开111.exe这个文件
{
printf( "FILE ERROR! ");
getchar();
return;
}
//send(sockConn,filename,strlen(filename),0);
printf( "初始化……\n ");
/*int Cmdtmp;
char Cmd=0;
Cmdtmp=send(sockConn,&Cmd,1,0);
while(Cmdtmp <1)
Cmdtmp=send(sockConn,&Cmd,1,0);
*/
getchar();
printf( "正在发送…… ");
char temp[1024];
while(!feof(fp)){
memset(temp,0,1024);
fread(temp,1024,1,fp);//读文件
int y = send(sockConn,temp,1024,0);
while(y <1024)
{
printf( "发送%d字节,不符合要求,重新发送\n ",y);
y=send(sockConn,temp,1024,0);//传送文件
}
}//while(feof)
fclose(fp);
closesocket(sockConn);
printf( "\n发送成功\n ");
}//while
}//main
接收端:
#include <Winsock2.h>
#include <stdio.h>
//连接一个库文件project-> setting-> link:object/library modules添加:ws2_32.lib
void main()
{
WORD wVersionRequested;//版本号
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//1.1版本的套接字
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}//加载套接字库,加裁失败则返回
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}//如果不是1.1的则退出
SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr=inet_addr( "192.168.18.71 ");
addrClient.sin_family=AF_INET;
addrClient.sin_port=htons(6000);
printf( "正在连接……\n ");
int x=connect(sockClient,(SOCKADDR*)&addrClient,sizeof(SOCKADDR));
while(x==-1)
{
printf( "connecting\n ");
x=connect(sockClient,(SOCKADDR*)&addrClient,sizeof(SOCKADDR));
}
FILE *fp;
if((fp=fopen( "1.exe ", "wb "))==NULL)
{
printf( "Failed in file creating.\n ");
getchar();
return;
}
printf( "连接成功!\n ",x);
printf( "正在接收……\n ");
/*char Cmd=0;
int tmp_int = recv(sockClient,&Cmd,1,0);//发送开始传送指令
while(tmp_int <1)
recv(sockClient,&Cmd,1,0);
*/
char temp[1024];
memset(temp,0,1024);
int IRecvLen;
IRecvLen=recv(sockClient,temp,1024,0);
//printf( "%d ",IRecvLen);
while(IRecvLen> 0)
{
if(IRecvLen==1024)
{
printf( "已写入%d bytes\n ",IRecvLen);
fwrite(temp,1024,1,fp);
}
else
printf( "接收到%d bytes.不符合要求,抛弃处理!\n ",x);
IRecvLen=recv(sockClient,temp,1024,0);
}
printf( "接收到%d bytes.不符合要求,抛弃处理!\n ",x);
fclose(fp);
closesocket(sockClient);
printf( "文件接收成功 ");
WSACleanup();
getchar();
}//main
[解决办法]
while(!feof(fp)){
memset(temp,0,1024);
fread(temp,1024,1,fp);//读文件
int y = send(sockConn,temp,1024,0);
while(y <1024)
{
printf( "发送%d字节,不符合要求,重新发送\n ",y);
y=send(sockConn,temp,1024,0);//传送文件
}
}
你这句是什么意思?当有个文件大小是1024*n+x(x <1024)个字节时怎么办?
[解决办法]
楼上说的对呀~~ 楼主少的文件字节不会多于1024吧
[解决办法]
发送部分:
int x, y;
while(!feof(fp)){
memset(temp,0,1024);
x = fread(temp,1024,1,fp);//读文件
while( x > 0 )
{
y = send(sockConn,temp + 1024 - x, x,0);
if( y > 0)
x -= y;
else
{
printf( "发送错误\n ",y);
break;
}
}
if (x > 0)
break;
}
fclose(fp);
sleep(1000); //不要立刻关闭连接
closesocket(sockConn);
接收部分:
一次发送1024个字符不等于一次能接收1024个字符,可能分成多次接收
while(IRecvLen> 0)
{
printf( "已写入%d bytes\n ",IRecvLen);
fwrite(temp,IRecvLen,1,fp);
IRecvLen=recv(sockClient,temp,1024,0);
}
[解决办法]
recv并不保证一次能接收到你指定长度的全部数据,接收到一个数据包,接收端可能需要多次recv才能接收完整一个包,然后进行组包。
最好在每个数据包前附加一个包头,告诉接收端应该接收的数据包实际长度,然后接收端先读取包头,根据这个包的长度继续进行接收,利用recv的返回值相加来判断一个数据包是否已经接收完整。