Reputation: 11
i want to send a file from client to server through socket . yes it sends a file but the received file in the server is not full or complete like the original one.
So the test file originally has "this is a test" in it, and the received file has "this"
yes it's only 4 letters
i tried to change the original one becomes "MyMomGoesToTheMarket"
and received file has "MyMo" . still 4 letters which is not what i expect.
anyone know how to solve this problem and the solution ?
Here is the client :
#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;
}
and here is the server code :
#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;
}
Upvotes: 0
Views: 64
Reputation: 3082
In your server code's recv
function, you're passing in sizeof(rbuffer)
as the amount of bytes to read in from the socket. rbuffer
is a pointer however, and thus taking a sizeof it will return the size of a pointer on your architecture , which is typically 4 or 8 bytes, and since your server code is only reading 4 bytes, sizeof(rbuffer)
would return 4 on your system.
To solve this, you need to pass in either Size
-1 or strlen(rbuffer)
-1 into the call to
int k = recv(ClientAcc, rbuffer, sizeof(rbuffer), NULL);
So it would look like this:
int k = recv(ClientAcc, rbuffer, Size-1, NULL);
This would actually read up to Size
-1 bytes from the socket. You would then need to add the null terminator to the end of rbuffer
.
rbuffer[k] = '\0';
Additionally, you need to make the same change in this line:
file.write(rbuffer, sizeof(rbuffer));
Which has the same problem as before - it only writes (in this case 4) bytes from rbuffer
.
Upvotes: 1