Josh Josh - 1 month ago 11
C Question

Weird file output socket file transferring

So, I'm making a socket program to connect two programs and everything works thus far; setting up winsock, connecting and interaction. However, the file being sent over from the client side to the server side has weird characters in it.

Example:

File: test.txt
Contents: Hey, how are you?
** Client sends file over to Server **
Expected Output: Hey, how are you?
Actual Output: 7_ Ä _


Server code:

int main() {
WSADATA Winsock;
SOCKET Socket, Sub;
Addr addr;
IncomingAddress incomingAddress;
int AddressLen = sizeof(IncomingAddress);

// Start up Winsock
WSAStartup(MAKEWORD(2, 2), &Winsock);

if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) {
WSACleanup();
return 0;
}

Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

// Memset alternative
ZeroMemory(&addr, sizeof(Addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(portNumber);
bind(Socket, (sockaddr*) &addr, sizeof(Addr));

if (listen(Socket, 1) == SOCKET_ERROR) {
printf("Listening error!\n");
} else {
printf("Listening...\n");
}

if (Sub = accept(Socket, (sockaddr*) &incomingAddress, &AddressLen)) {
int Size;
char *Filesize = malloc(MAX_PATH);

if (recv(Socket, Filesize, MAX_PATH, 0)) { // File Size
Size = atoi((const char*) Filesize);
printf("File size: %d\n", Size);
}

char *Buffer = malloc(Size);

int Offset = 0;
while (Size > Offset) {
printf("TESST");
int Amount = recv(Socket, Buffer + Offset, Size - Offset, 0);

if (Amount <= 0) {
printf("Error: " + WSAGetLastError());
break;
} else {
Offset += Amount;
}
}

FILE *File;
File = fopen("test.txt", "wb+");
fwrite(Buffer, 1, Size, File);
fclose(File);

getchar();
closesocket(Socket);
WSACleanup();

}
}
return 0;
}


Client code:

int main() {
WSADATA Winsock;
SOCKET Socket, Sub;
Addr addr;
IncomingAddress incomingAddress;
int AddressLen = sizeof(IncomingAddress);

WSAStartup(MAKEWORD(2, 2), &Winsock);

if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) {
WSACleanup();
return 0;
}

Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

ZeroMemory(&addr, sizeof(Addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(6000);

if (connect(Socket, (sockaddr*) &addr, sizeof(Addr)) < 0) {
printf("Connection Failed!\n");
getchar();
return 0;
}

char *ClientIP = inet_ntoa(incomingAddress.sin_addr);
int ClientPort = ntohs(incomingAddress.sin_port);
printf("Client connected!\n");
printf("IP: %s:%d\n", ClientIP, ClientPort);

printf("Sending file... \n");

FILE *File;
char *Buffer;
unsigned long Size;

File = fopen("test.txt", "rb+");
if (!File) {
printf("Error while reading the file!\n");
getchar();
return 0;
}

fseek(File, 0, SEEK_END);
Size = ftell(File);
fseek(File, 0, SEEK_SET);

Buffer = malloc(Size);

fread(Buffer, Size, 1, File);
char cSize[MAX_PATH];
sprintf(cSize, "%i", Size);

fclose(File);
send(socket, cSize, MAX_PATH, 0); // File size

int Offset = 0;
while (Size > Offset) {
int Amount = send(Sub, Buffer + Offset, Size - Offset, 0);

if (Amount <= 0) {
printf("Error: " + WSAGetLastError());
break;
} else {
Offset += Amount;
}
}
free(Buffer);
closesocket(Sub);
closesocket(Socket);
WSACleanup();
printf("File sent!\n");
return 0;
}

Answer

You have three problems, one in the client and two in the server.

In the client you are sending the size of the file through Socket, which is correct. But then you use the unconnected and uninitialized socket Sub to send the data of the file.

In the server you have almost the opposite problem, where you attempt to receive both the size and the data through the passive listening socket instead of the accepted connection socket Sub.

Also in the server, if there's an error when reading the data you report it, but then you write data to the file anyway. In this case it will be some uninitialized data of unknown length.

Use correct sockets, and if there's an error don't do things you should not do.

And actually do some error checking. When receiving the size in the server, you don't check for errors, just that the connection wasn't closed by the other end of the connection.