我想通过套接字将文件从客户端发送到服务器。是的,它发送一个文件,但是服务器中接收到的文件不像原始文件一样完整或完整。
因此,测试文件中最初包含“ this is a test”,而接收到的文件中包含“ this”
是的,只有四个字母
我试图将原来的变成“ 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:%d\n", ClientIP, ClientPort);
}
void receiving() {
//receive the file size
recv(ClientAcc,Filesize,1024,0);
Size = atoi((const char*)Filesize);
printf("File size : %d\n",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
是一个指针,因此采用sizeof它将返回架构上的指针大小,通常为4或8个字节,并且由于服务器代码仅读取4个字节,因此sizeof(rbuffer)
将返回4在您的系统上。
要解决此问题,您需要将Size
-1或strlen(rbuffer)
-1传递给
int k = recv(ClientAcc, rbuffer, sizeof(rbuffer), NULL);
所以它看起来像这样:
int k = recv(ClientAcc, rbuffer, Size-1, NULL);
实际上,这将从套接字读取最多
Size
-1个字节。然后,您需要将空终止符添加到rbuffer
的末尾。rbuffer[k] = '\0';
此外,您需要在此行中进行相同的更改:
file.write(rbuffer, sizeof(rbuffer));
与以前有同样的问题-它仅从
rbuffer
写入(在这种情况下为4)字节。