C++ - 文件未满到达
C++ - File is not Full arrived
我想通过套接字将文件从客户端发送到服务器。 是的,它发送一个文件,但服务器中收到的文件不像原始文件那样完整或完整。
所以测试文件中原本有"这是一个测试",收到的文件有"这个"
是的,只有 4 个字母
我试图将原来的变成"MyMomGoesToTheMarket"并且收到的文件有"MyMo"。 仍然有4个字母,这不是我所期望的。
有人知道如何解决这个问题和解决方案吗?
这是客户端:
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
using namespace std;
SOCKET clientsock;
WSADATA winsock;
sockaddr_in serverAddr , addr;
int Addrlen = sizeof(serverAddr);
FILE *File;
unsigned long Size;
void startClient() {
WSAStartup(MAKEWORD(2,2), &winsock);
if(LOBYTE(winsock.wVersion) != 2 || HIBYTE(winsock.wVersion) != 2 ){
WSACleanup();
}
clientsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(6091);
connect(clientsock,(sockaddr*)&addr,sizeof(addr));
printf("socket connected... n");
}
void sending() {
//preparing the file
ifstream myfile;
myfile.open("B:RelativeLayout.txt",ios::in | ios::binary | ios::ate);
if(myfile.is_open()) {
printf("File open OK ! n ");
}else {
printf("File not open ! n ", WSAGetLastError());
}
//preparing the file size
long Size ;
myfile.seekg(0,fstream::end);
Size = myfile.tellg();
myfile.close();
printf("File Size : %d bytes.n ",Size);
char cisi[10];
sprintf(cisi, "%i",Size);
send(clientsock,cisi,10,0); // file size sent
//sending the file
char *rbuffer;
myfile.open("B:RelativeLayout.txt",ios::in | ios::binary | ios::ate);
if(myfile.is_open()) {
myfile.seekg(0, ios::beg);
rbuffer = new char[Size];
myfile.read(rbuffer, Size);
//send(clientsock, rbuffer, Size, 0);
int j = send(clientsock, rbuffer, Size, NULL); //send to server
if (j == -1){
cout << "Error sending file to server :(" << endl;
}else {
cout << " sending file to server succeed" << endl;
}
myfile.close();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
startClient();
sending();
system("PAUSE");
return 0;
}
这是服务器代码:
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <fstream>
using namespace std;
SOCKET servsocket, ClientAcc;
WSAData winsock;
sockaddr_in addr,incomingAddress;
int addrlen = sizeof(sockaddr_in);
int addresslen = sizeof(incomingAddress);
char *Filesize = new char[1024];
long Size;
void start() {
//socket initialization
WSAStartup(MAKEWORD(2,2), &winsock);
//socket check
if(LOBYTE(winsock.wVersion) !=2 || HIBYTE(winsock.wVersion) != 2 ) {
WSACleanup();
}
servsocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
addr.sin_family = AF_INET;
addr.sin_port = htons(6091);
bind(servsocket, (sockaddr*)&addr, sizeof(addr));
listen(servsocket, 5);
ClientAcc = accept(servsocket, (sockaddr*)&incomingAddress, &addresslen);
char *ClientIP = inet_ntoa(incomingAddress.sin_addr);
int ClientPort = ntohs(incomingAddress.sin_port);
printf("Client Connected ... n");
printf("IP : %s:%dn", ClientIP, ClientPort);
}
void receiving() {
//receive the file size
recv(ClientAcc,Filesize,1024,0);
Size = atoi((const char*)Filesize);
printf("File size : %dn",Size);
//receive the file
char *rbuffer;
rbuffer = new char[Size];
int k = recv(ClientAcc, rbuffer, sizeof(rbuffer), NULL);
if (k < 0){
cout << "Error uploading file" << endl;
}else {
fstream file;
file.open("B:FileReceived.txt", ios::out|ios::binary| ios::ate);
file.write(rbuffer, sizeof(rbuffer));
file.close();
cout << "File received!" << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
start();
receiving();
system("PAUSE");
return 0;
}
在服务器代码的recv
函数中,将sizeof(rbuffer)
作为要从套接字读入的字节数传入。 然而,rbuffer
是一个指针,因此取一个大小它将返回你的架构上指针的大小,通常是 4 或 8 个字节,并且由于您的服务器代码只读取 4 个字节,sizeof(rbuffer)
会在您的系统上返回 4
要解决此问题,您需要将 -1 Size
或 strlen(rbuffer)
-1 传递到调用
int k = recv(ClientAcc, rbuffer, sizeof(rbuffer), NULL);
所以它看起来像这样:
int k = recv(ClientAcc, rbuffer, Size-1, NULL);
这实际上会从套接字读取多达 Size
-1 个字节。然后,您需要将空终止符添加到 rbuffer
的末尾。
rbuffer[k] = ' ';
此外,您需要在此行中进行相同的更改:
file.write(rbuffer, sizeof(rbuffer));
它与以前有相同的问题 - 它只从 rbuffer
写入(在本例中为 4)字节。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 如何将内容数组写入文本文件?
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到