469,645 Members | 1,634 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,645 developers. It's quick & easy.

How to flush socket buffer in C++ (Not VC++.NET)

Can anyone tell me how to flush a socket stream in C++.
I am making an Client Server application in C++ and use the send() and recv() functions. i want to flush the socket buffer as i am getting unwanted data when i use recv().

A part of my server code is like this:


int bytesRecv = SOCKET_ERROR;
char recvbuf[1]="";
int ch ;
bytesRecv = recv( clientSocket, recvbuf, 1, 0 );

the problem is : when i print the contents of recvbuf i get garbage values with the values sent to the server.

Can anyone help me in this situation.Someone told me to flush the socket buffer. Is this the right solution??

Pawan
Feb 9 '07 #1
6 37088
horace1
1,510 Expert 1GB
Can anyone tell me how to flush a socket stream in C++.
I am making an Client Server application in C++ and use the send() and recv() functions. i want to flush the socket buffer as i am getting unwanted data when i use recv().

A part of my server code is like this:


int bytesRecv = SOCKET_ERROR;
char recvbuf[1]="";
int ch ;
bytesRecv = recv( clientSocket, recvbuf, 1, 0 );

the problem is : when i print the contents of recvbuf i get garbage values with the values sent to the server.

Can anyone help me in this situation.Someone told me to flush the socket buffer. Is this the right solution??

Pawan
recv() returns the number of bytes actually read into the buffer so you should be able to ignore anything else.
As far as I know flush only works on output streams??
Feb 9 '07 #2
recv() returns the number of bytes actually read into the buffer so you should be able to ignore anything else.
As far as I know flush only works on output streams??
Thanks for your interest in my post.
But can you state clearly what you mean by output stream, and does sockets in C++ does not require flushing? Actually, initially i was transferring a file from Client to Server, and even after sending the last set of bytes of file to the server, the server was still waiting at the recv() function.

A snippet of my code is here :

void getFile(SOCKET c_socket)
{
char *memblock;
int num_of_bytes,file_buf = 100000; //any user specific number of bytes
memblock = new char [file_buf];

//dest file
ofstream dest("c:\\dest\\umg.rar",ios::app | ios::binary);

while(true)
{
//reading "num_of_bytes" byte(s) from sourcefile
num_of_bytes = recv( c_socket, memblock, file_buf, 0 );

//writing "num_of_bytes" byte(s) to destination file
dest.write(memblock,num_of_bytes);

//last bunch of bytes recieved
if(num_of_bytes == 0) break;

}

//closing source and destination files.
dest.close();

printf("\n The file was successfully copied.\n");

delete memblock;
//system("pause");

return;
}


here the while loop never terminates and the control again reaches to the recv() function.
When i see the file in this case(i.e. when the control is inside the loop and the program still running) it is not copied at the server and some bytes are remaining. And when i closed the apllication, the remaining bytes were copied to the file.

One of my friend told me that some bytes are still in the buffer which are copied to the file and when i close the application, those remaining bytes from the buffer are copied to the file. To eliminate this he told me to use this condition instead :

//last bunch of bytes recieved
if(num_of_bytes < file_buf) break;

so this worked fine. But he still says that i should have flushed the socket buffer instead, either before sending the bytes or after receiving.

Please Help.
Pawan
Feb 9 '07 #3
RRick
463 Expert 256MB
You are close, but have a couple of issues with your code.

At the very top, your recbuff variable is only one character. If you try to print this, it will be treated as a string and will print until a '\000' character is found. This is probably the garbage you found in your printout. The garbage is not from the socket, but from reading past the end of your string. Since you only get a single char, then define it that way: char recbuf;. Now when you print it out, it will be treated a single char. That said, sooner or later you will hang on recv because it blocks when no data is available (see below).

Further down, the code will hang because recv is blocking. You read all the data, but then went back and read more. Now you will block forever. You can change the socket to non-blocking, but you probably don't need to do that.

For your code, first, don't malloc a big chunk of data, just declare it locally. That is: char buff[MaxXxxx];. This will save some time and clean up.

Next do as your friend suggests, if the bytes read is less than MaxXxxx, then you have read everything and can leave. I've always wondered what would happen if you sent exactly the size of your buffer. I guess bad things will happen.

Lastly, there are no sockets in C++. Sockets are implemented through system level routines. These routines tend be very low level. You are in control and completely in control. You have to know how much data is being sent and what kind of data is being sent. If your server stops in the middle of sending data, you have to figure out if you need to do another recv. If you use single sends and recvs, then this is not usually a problem.

Cheers
Feb 10 '07 #4
Thanks for a detail reply.

I think the conversion from char array to a single byte char variable will do here, but what if I am receiving more than 1 byte say a file from the client? In that case I will have to use an array. Please reply.

Secondly,
when my friend told me the

//last bunch of bytes recieved
if(num_of_bytes < file_buf) break;

condition, I also thought the same that when the file with exactly the same size will come, then what will happen?

So if I don't use this way, then what can I do? How can I prevent the loop to block at recv().

He also told me that I can send any dummy value like "OK" or "DONE" etc... when all the bytes of the file have been sent from the client end, I tried this but my Server was unable to understand this dummy value, so it again blocked at recv(). I am not getting any other way, please show me some way.

Pawan
Feb 10 '07 #5
RRick
463 Expert 256MB
Don't expect recv to tell you very much. When you pass the buffer and size (say 100) to recv, you're saying that this is the most data I can handle. Recv will send what ever it has, up to 100 chars. If it has more, then you have to figure out if you want to call recv again. Recv won't tell you if it has more. If recv has less that 100 chars, it will send that and tell you how much it sent. If there is no data, then Recv waits or blocks until something arrives. Now, go back and read this until you understand.

One choice is to make your buffer bigger than whatever the server sends. One read with recv and you're done. (This is your best option).

If your buffer is small, then you will have to loop until you receive all the info. You have to figure out if you need more info; recv will not help you.

One trick is to make recv not block or wait, but this is not for the faint of heart. In linux, the ioctl function can do this, but you'll have to google for more info. When recv does not block, it will return a 0 size, if no data exists. Unfortunately, this opens up other problems. What if you're too fast and call recv before the server sends something? There is also a issue with a "busy wait" while in a loop waiting some data. This can be a real performance issue.

Good luck.
Feb 10 '07 #6
Hi,

I think timeout is what you want to ask.... check the bellow link at "How can I implement a timeout on a call to recv()?"

http://retran.com/beej/faq.html

Hope this help..
Mar 6 '07 #7

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

5 posts views Thread by pnigl | last post: by
3 posts views Thread by Robert A. van Ginkel | last post: by
2 posts views Thread by Kiran | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.