2

I am currently working on a SCTP server-client pair for Linux that needs to send files over one stream. This is because other streams will be used to send commands, telemetry, etc. I am using QT creator if that helps at all. It is a requirement that I use SCTP for this. The server and client are running as separate applications over a local port as of right now.

Here are the important code snippets. Both the client and server are running in separate threads from their respective main()s, this allows for additional code implementation in the future.

/*
*Server (Sending side):
*/
std::ifstream inFile("/home/username/test.png", std::ios::binary);
char buf[MAX_BUFFER+1];
while(inFile.read((char *)buf,sizeof(buf)))
{
   //Sends the current buffer over stream 3
   snd_ret = sctp_sendmsg( goodSock, (void *)buf, (size_t)strlen(buf),
                               NULL, 0, 0, 0, 3, 0, 0 ); 
   /*
   * in another thread there is a loop that receives messages
   * the client side sends a message whenever it receives
   * this ensures the data was sent and waits before sending more.
   */
   while(confirmHandshake == false){/*...*/}
   //delays so I can view and compare console outputs for debugging
   std::this_thread::sleep_for(std::chrono::milliseconds(200));
 }

I currently also have the write the buffers it reads into a separate png using ofstream. That aspect works for the most part; it doesn't read and write the entire file, but that is the least of my concerns right now.

/*
* Client (Recieving Side)
*/
//creates a file if it isn't there
std::ofstream file("write.png");
//instantiates ofstream
std::ofstream ofs;
//opens the file using binary, I've tried it with "| std::ios::out" too
ofs.open ("write.png", std::ios::binary);
//tried different buffer sizes, same results, currently set at 512
char inBuffer[MAX_BUFFER+1];
while(error != -1){
     memset(inBuffer, 0, MAX_BUFFER+1);
         in = sctp_recvmsg( connSock, (void *)inBuffer              
             , sizeof(inBuffer), (struct sockaddr *)NULL, 0
             , &sndrcvinfo, &flags);
     if( in != -1 && sndrcvinfo.sinfo_stream == 3){
         //writes the buffer to the file every time it recieves
         //I've tried changing the pointers around,
         //also tried using sizeof() instead of strlen()
         //this changed the results, nothing worked so far
         ofs.write((char *)&inBuffer, strlen(inBuffer));
         //sends a handhake message (stored in s_buffer) to server
         snd_ret = sctp_sendmsg( connSock, (void *)s_buffer 
             ,(size_t)strlen(s_buffer) 
             ,NULL, 0, 0, 0, 4, 0, 0 );
     } 
}

The problem I'm facing is that the data received is different from the data sent. The data sent seems to be fine, because I can write that buffer to a file without file corruption. When I open the png written to on the client end, the picture cannot be displayed, there were various errors depending on the different changes I made in my attempts to debug this. I'm not sure where the data is going bad, is it over the socket, or writing the file. The garbled ASCII representations I get when I print both sides into their consoles look almost identical.

I would also like to know if there are any better solutions for reading and writing the file. Or different types of data to send the data as (I think \n might be one problem). I was thinking potentially trying to convert the file to hex for transmission and converting back to binary if all else fails. I want to try to make it work with just binary, however.

Another thing I was wondering: is it possible to simply use socket.h's send and recv functions simultaneously with sctp_sendmsg and sctp_recvmsg. I assume it would just hang the program but I have little experience with socket protocols.

I'm open to any other suggestions as well. As long as it is still using SCTP with streams.

Thanks!

0 Answers0