无法使用 recv() 传输最后一个数据包 Server/Client C 文件通过 TCP 传输
Can not Transmit last packet with recv() Server/Client C file Transmiting over TCP
我一直在尝试通过 windows 客户端上的 TCP\IP 将文件传输到 Linux 服务器。
这几天一直是一个主要问题,因为缺乏理解为什么服务器端没有收到最后一个数据包,这会阻止文件的写入。
我想实现的是下载图片(JPG、PNG)、程序(EXE)等..
输出
客户
lltoa(size.QuadPart,container,10);
//Send file size
send(sock, container, sizeof(container), 0);
bzero(container,1024);
//End of file size
unsigned __int64 uiPos = 0;
unsigned __int64 uiRemaining = ul.QuadPart;
while (uiRemaining > 0)
{
ul.QuadPart = uiPos;
ov.Offset = ul.LowPart;
ov.OffsetHigh = ul.HighPart;
DWORD dwNumToSend = (uiRemaining <= 3) ? 1 :1024; //(DWORD)uiRemaining;
if (!TransmitFile(sock,get_file, dwNumToSend, 0, &ov, NULL, 0))
{
if ((GetLastError() != ERROR_IO_PENDING) && (WSAGetLastError() != WSA_IO_PENDING))
break;
WaitForSingleObject(ov.hEvent, INFINITE);
}
uiPos += dwNumToSend;
uiRemaining -= dwNumToSend;
//Sleep(1);
}
CloseHandle(ov.hEvent);
CloseHandle(get_file);
服务器
file_size = atoi(response);
printf("File size: %lli \n",file_size);
bzero(response,18384);
//End of file size
//First packet of file
len = recv(client_socket,response,sizeof(response)<file_size?(sizeof(response)):file_size,MSG_WAITALL);
printf("Received: %i \n",len);
if (len == 0)
{
printf("Error downloading file!");
goto jump;
}
file_size = file_size - len;
int counter = 0;
while(file_size > 0)
{
//Start getting the file
fwrite(response,1,len,new_file);
bzero(response,18384);
len = recv(client_socket,response,((file_size <= 1024) || (len < 1024))?file_size:sizeof(response),MSG_WAITALL);
printf("Received: %i\t|",len);
if(len <= 0)
{
break;
}
//Check if this is the last packet
file_size = file_size - len;
printf("Response #%i\tbytes_received: %i\tbytes remain:%li \n",counter,len,file_size);
counter += 1;
}
if(file_size > 0)
{
printf("\t\t\tError downloading file! bytes left:%li \n",file_size);
}
else
{
printf("Successfully downloaded file! \n");
}
fclose(new_file);
goto jump;
recv() 处理错误:
如果需要更多服务器端代码,请发表评论。我认为这可以做到。
谢谢!!
根据您展示的代码,发现了一些问题。如下编辑后对我有用。你可以试试看。 (如果您仍然有问题,请显示 ul.QuadPart
、ul.LowPart
和 ul.HighPart
相关代码。)
在客户端:
将DWORD dwNumToSend = (uiRemaining <= 3) ? 1 :1024;
更改为DWORD dwNumToSend = (uiRemaining <= 1024) ? uiRemaining : 1024;
在服务器端:
将((file_size <= 1024) || (len < 1024))?file_size:sizeof(response)
更改为(file_size <= sizeof(response))?file_size:sizeof(response)
我一直在尝试通过 windows 客户端上的 TCP\IP 将文件传输到 Linux 服务器。 这几天一直是一个主要问题,因为缺乏理解为什么服务器端没有收到最后一个数据包,这会阻止文件的写入。
我想实现的是下载图片(JPG、PNG)、程序(EXE)等..
输出
客户
lltoa(size.QuadPart,container,10);
//Send file size
send(sock, container, sizeof(container), 0);
bzero(container,1024);
//End of file size
unsigned __int64 uiPos = 0;
unsigned __int64 uiRemaining = ul.QuadPart;
while (uiRemaining > 0)
{
ul.QuadPart = uiPos;
ov.Offset = ul.LowPart;
ov.OffsetHigh = ul.HighPart;
DWORD dwNumToSend = (uiRemaining <= 3) ? 1 :1024; //(DWORD)uiRemaining;
if (!TransmitFile(sock,get_file, dwNumToSend, 0, &ov, NULL, 0))
{
if ((GetLastError() != ERROR_IO_PENDING) && (WSAGetLastError() != WSA_IO_PENDING))
break;
WaitForSingleObject(ov.hEvent, INFINITE);
}
uiPos += dwNumToSend;
uiRemaining -= dwNumToSend;
//Sleep(1);
}
CloseHandle(ov.hEvent);
CloseHandle(get_file);
服务器
file_size = atoi(response);
printf("File size: %lli \n",file_size);
bzero(response,18384);
//End of file size
//First packet of file
len = recv(client_socket,response,sizeof(response)<file_size?(sizeof(response)):file_size,MSG_WAITALL);
printf("Received: %i \n",len);
if (len == 0)
{
printf("Error downloading file!");
goto jump;
}
file_size = file_size - len;
int counter = 0;
while(file_size > 0)
{
//Start getting the file
fwrite(response,1,len,new_file);
bzero(response,18384);
len = recv(client_socket,response,((file_size <= 1024) || (len < 1024))?file_size:sizeof(response),MSG_WAITALL);
printf("Received: %i\t|",len);
if(len <= 0)
{
break;
}
//Check if this is the last packet
file_size = file_size - len;
printf("Response #%i\tbytes_received: %i\tbytes remain:%li \n",counter,len,file_size);
counter += 1;
}
if(file_size > 0)
{
printf("\t\t\tError downloading file! bytes left:%li \n",file_size);
}
else
{
printf("Successfully downloaded file! \n");
}
fclose(new_file);
goto jump;
recv() 处理错误:
谢谢!!
根据您展示的代码,发现了一些问题。如下编辑后对我有用。你可以试试看。 (如果您仍然有问题,请显示 ul.QuadPart
、ul.LowPart
和 ul.HighPart
相关代码。)
在客户端:
将DWORD dwNumToSend = (uiRemaining <= 3) ? 1 :1024;
更改为DWORD dwNumToSend = (uiRemaining <= 1024) ? uiRemaining : 1024;
在服务器端:
将((file_size <= 1024) || (len < 1024))?file_size:sizeof(response)
更改为(file_size <= sizeof(response))?file_size:sizeof(response)