I'm facing a problem.
I have the server code made in C ++, running on ubuntu.
And I have the client code done in C #, running on windows.
In the code made in the server (C ++) I came across a problem
//recebe tamanho arquivo
read(idSockfd, tmpBuffer, BUFSIZ_SOCKET);
int file_size = atoi(tmpBuffer);
bzero(tmpBuffer,BUFSIZ_SOCKET);
//recebe outra instrucao
read(idSockfd, tmpBuffer, BUFSIZ_SOCKET);
This worked when I sent the request from my computer (Windows 10), but on other computers like Windows 7 the "second" read
, went straight, as if it had sent something in the buffer.
To solve this problem, after a search I found the following solution:
Passing the parameter MSG_WAITALL
, this solved the problem. On all tested computers it worked ..
recv(idSockfd, tmpBuffer, BUFSIZ_SOCKET, MSG_WAITALL);
While I have a function that receives files
FILE* received_file = fopen(fileName.c_str(), "w");
if (received_file == NULL)
{
printf("Erro ao receber o arquivo\n");
}
bzero(tmpBuffer,BUFSIZ_SOCKET);
int remain_data = file_size;
int len;
while (((len = recv(idSockfd, tmpBuffer, BUFSIZ_SOCKET, MSG_WAITALL)) > 0) && (remain_data > 0))
{
fwrite(tmpBuffer, sizeof(char), len, received_file);
remain_data -= len;
fprintf(stdout, "Recebendo %d bytes e falta:- %d bytes\n", len, remain_data);
}
printf("Fechando arquivo\n");
fclose(received_file);
It turns out that the "last" part of the file will always be smaller than the buffer size, and with the MSG_WAITWALL statement, it waits for the entire buffer, and never receives the last bytes of the file.
I tried to change it to the following way too
(((len = recv(idSockfd, tmpBuffer, BUFSIZ_SOCKET, 0)) > 0) && (remain_data > 0))
(((len = recv(idSockfd, tmpBuffer, BUFSIZ_SOCKET, 0)) > MSG_TRUNC) && (remain_data > 0))
(((len = recv(idSockfd, tmpBuffer, BUFSIZ_SOCKET, 0)) > MSG_PEEK) && (remain_data > 0))
(((len = recv(idSockfd, tmpBuffer, BUFSIZ_SOCKET, 0)) > MSG_PEEK | MSG_TRUNC) && (remain_data > 0))
But all my attempts were thwarted.
Follow the C # code that sends the file ..
Socket s = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
s.Connect(conn.Ip, conn.Port);
buffer = new byte[102400];
//envia o lenght
byData = System.Text.Encoding.ASCII.GetBytes(new FileInfo(f.FileName).Length.ToString());
byData.CopyTo(buffer, 0);
debug = s.Send(buffer);
//envia o caminho
byData = System.Text.Encoding.ASCII.GetBytes(path);
byData.CopyTo(buffer, 0);
debug = s.Send(buffer);
//envia o arquivo
s.SendFile(f.FileName);
How can I make a guarantee of what is received is what the client application sent and not some "dirt", I say "dirt" because on computers tested with windows 7, it receives a few bytes that I honestly do not know where it came from .
Thanks for your attention and help right away.