Socket between C++ and C#

Asked

Viewed 159 times

1

I’m facing a problem.

I have the server code done in C++, running in Ubuntu.

And I have the client code done in C#, running in windows.

In the server code (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 or "second" read, like he sent something through 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);

However 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 instruction MSG_WAITWALL, is waiting for the whole buffer, and never gets the last bytes of the file.

I tried to change 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 have a guarantee of what receives is what the client application sent and not some "dirt", I say "dirt" because on computers tested with windows 7, receives a few bytes that honestly do not know where it came from.

Thanks for your attention and help.

  • Is this processing synchronous? Instead of MSG_WAITALL, you could use a monitor or semaphore for thread control?

  • Originally is a thread, but I did tests on the main function, and the same problem happens..

  • 1

    I found your description of the problem a little confusing...see if the answer I gave to this question help...what I can say is that I never had to use this flag MSG_WAITALL, and this flag will actually cause the problem that you reported last, that the application is stuck waiting to receive all the BUFSIZ_SOCKET bytes

  • @Joséx. Thank you for your reply.. I will test, but probably this is what was happening, as you wrote in the reply 300 bytes can reach in 3 parts of 100 bytes. Thank you.

  • The correct one would be to have a file waiting state and another acquiring the file for example. Give read in 1 byte until you have been able to read 4 bytes. With these 4 bytes, you have the file size. Read 1 to 1 just like you did with the size and concatenating the buffer. At least this way I never had package problems in half or something as reported

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.