473,386 Members | 1,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Buffer size when receiving data through a socket?

I wrote some pretty basic socket programming again, but I'm still confused about what's happening with the buffer_size variable. Here are the server and client programs:

--------------

from socket import *

host = ''
port = 51567
address = (host, port)
buffer_size = 1024

server_socket = socket(AF_INET, SOCK_STREAM)
server_socket.bind(address)
server_socket.listen(5)

while True:
print 'waiting for connection...'
client_socket, client_address = server_socket.accept()
print '...connected from:', client_address

while True:
data = client_socket.recv(buffer_size)
if not data:
break
client_socket.send('%s %s' % ('You typed:', data))

client_socket.close()

server_socket.close()

------------

from socket import *

host = 'localhost'
port = 51567
address = (host, port)
buffer_size = 1024

client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(address)

while True:
data = raw_input('')
if not data:
break
client_socket.send(data)
data = client_socket.recv(buffer_size)
if not data:
break
print data

client_socket.close()

---------------

I tried changing buffer_size to 10 and I got this output:

john@john-laptop:~$ python myclient.py
hello
You typed:
something
hello
this is a long string
You typed:
why doesn't this work right
something
>
john@john-laptop:~$

My first question is, isn't buffer_size the number of bytes being sent at one time? If so, why doesn't 'hello' get printed after the server returns the data to the client? Isn't 'hello' just 5 bytes?

Secondly, how is it working that once I type in a new string (e.g. 'something') and then the server returns data to the client, it prints the *previous* string, (i.e. 'hello')? Wouldn't the data variable get overwritten with the value, or is the value being stored somewhere else at this point?

Thanks!
Jun 27 '08 #1
10 34424
En Mon, 16 Jun 2008 21:21:35 -0300, John Salerno <jo******@NOSPAMgmail.comescribió:
I wrote some pretty basic socket programming again, but I'm still confused about what's happening with the buffer_size variable. Here are the server and client programs:

--------------

from socket import *

host = ''
port = 51567
address = (host, port)
buffer_size = 1024

server_socket = socket(AF_INET, SOCK_STREAM)
server_socket.bind(address)
server_socket.listen(5)

while True:
print 'waiting for connection...'
client_socket, client_address = server_socket.accept()
print '...connected from:', client_address

while True:
data = client_socket.recv(buffer_size)
if not data:
break
client_socket.send('%s %s' % ('You typed:', data))

client_socket.close()

server_socket.close()

------------

from socket import *

host = 'localhost'
port = 51567
address = (host, port)
buffer_size = 1024

client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(address)

while True:
data = raw_input('')
if not data:
break
client_socket.send(data)
data = client_socket.recv(buffer_size)
if not data:
break
print data

client_socket.close()

---------------

I tried changing buffer_size to 10 and I got this output:

john@john-laptop:~$ python myclient.py
>hello
You typed:
>something
hello
>this is a long string
You typed:
>why doesn't this work right
something
>>
john@john-laptop:~$

My first question is, isn't buffer_size the number of bytes being sent at one time? If so, why doesn't 'hello' get printed after the server returns the data to the client? Isn't 'hello' just 5 bytes?
Both programs say recv(buffer_size) - buffer_size is the maximum number of bytes to be RECEIVED, that is, READ. recv will return at most buffer_size bytes. It may return less than that, even if the other side sent the data in a single operation.
Note that most of the time you want to use the sendall() method, because send() doesn't guarantee that all the data was actually sent. <http://docs.python.org/lib/socket-objects.html>
Secondly, how is it working that once I type in a new string (e.g. 'something') and then the server returns data to the client, it prints the *previous* string, (i.e. 'hello')? Wouldn't the data variable get overwritten with the value, or is the value being stored somewhere else at this point?
Yes, it is stored in an intermediate buffer until you read it. You typed "hello" and sent it, the server replied with the string "You typed: hello"; the OS stores it. You read only 10 bytes "You typed:", the remaining are still in the buffer. Next round: you type something, the server replies, you read the remaining bytes from the original reply, and so on...

(Note that in this particular configuration, the client will fill its buffer at some time: because the server sends at least 11 bytes each round, but the client reads at most 10 bytes, so the client is always behind the server...)

--
Gabriel Genellina

Jun 27 '08 #2
"Gabriel Genellina" <ga*******@yahoo.com.arwrote in message
news:ma*************************************@pytho n.org...
Both programs say recv(buffer_size) - buffer_size is the maximum number of
bytes to be RECEIVED, that is, READ. recv will return at most buffer_size
bytes. It may return less than that, even if the other side sent the data
in a single operation.
Note that most of the time you want to use the sendall() method, because
send() doesn't guarantee that all the data was actually sent.
<http://docs.python.org/lib/socket-objects.html>
I was wondering about sendall(). The examples I've read in two different
books are consistent in their use of send() and don't even mention
sendall(), so I thought maybe it was for a more specialized situation.
Yes, it is stored in an intermediate buffer until you read it. You typed
"hello" and sent it, the server replied with the string "You typed:
hello"; the OS stores it. You read only 10 bytes "You typed:", the
remaining are still in the buffer. Next round: you type something, the
server replies, you read the remaining bytes from the original reply, and
so on...
Oh!!!! I didn't even count "You typed:" as part of the 10 bytes! And what a
coincidence that it happens to be exactly 10 characters! That really helped
to hide the problem from me!
(Note that in this particular configuration, the client will fill its
buffer at some time: because the server sends at least 11 bytes each
round, but the client reads at most 10 bytes, so the client is always
behind the server...)
How is the server sending back 11 bytes? Is it because it's sending at least
the 10 characters, plus the extra space?

Thanks!
Jun 27 '08 #3
"John Salerno" <jo******@NOSPAMgmail.comwrote in message
news:20******************************@NOSPAMgmail. com...
from socket import *

host = 'localhost'
port = 51567
address = (host, port)
buffer_size = 1024

client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(address)

while True:
data = raw_input('')
if not data:
break
client_socket.send(data)
data = client_socket.recv(buffer_size)
if not data:
break
print data

client_socket.close()
Also, is that second "if not data: break" statement necessary? It seems like
once you get past the first if, you don't need the second one. Of course, I
guses it's possible that the server could return a False value, but even
still, would it make sense to break out of the loop and close the connection
because of that?

It runs fine without the if statement, but I'm wondering if I just haven't
encountered the proper problem situation yet.
Jun 27 '08 #4
"Gabriel Genellina" <ga*******@yahoo.com.arwrote in message
news:ma*************************************@pytho n.org...
Note that most of the time you want to use the sendall() method, because
send() doesn't guarantee that all the data was actually sent.
<http://docs.python.org/lib/socket-objects.html>
If I use sendall(), am I still recv'ing data with a given buffer size? What
if I send more data than the buffer size. Is my code as written not prepared
to handle that case? It seems like I might need to continue receiving data
until there is no more to receive (in a loop?)...is that right?
Jun 27 '08 #5
En Tue, 17 Jun 2008 10:34:24 -0300, John Salerno <jo******@nospamgmail.comescribió:
I was wondering about sendall(). The examples I've read in two different
books are consistent in their use of send() and don't even mention
sendall(), so I thought maybe it was for a more specialized situation.
«Stream sockets (e.g., TCP sockets) exhibit a behavior with the read and write functions that differs from normal file I/O. A read or write on a stream socket might input or output fewer bytes than requested, but this is not an error condition. The reason is that buffer limits might be reached for the socket in the kernel. All that is required to input or output the remaining bytes is for the caller to invoke the read or write function again. Some versions of Unix also exhibit this behavior when writing more than 4,096 bytes to a pipe. This scenario is always a possibility on a stream socket with read, but is normally seen with write only if the socket is nonblocking. Nevertheless, we always call our writen function instead of write, in case the implementation returns a short count.» [1]

The Python `sendall` method is equivalent to the `writen` function they refer to. Rather than analyzing in each case whether sendall is to be required or not, I prefer to always use it and forget about it...
Oh!!!! I didn't even count "You typed:" as part of the 10 bytes! And what a
coincidence that it happens to be exactly 10 characters! That really helped
to hide the problem from me!
:)
>(Note that in this particular configuration, the client will fill its
buffer at some time: because the server sends at least 11 bytes each
round, but the client reads at most 10 bytes, so the client is always
behind the server...)

How is the server sending back 11 bytes? Is it because it's sending at least
the 10 characters, plus the extra space?
Yes, 10 + whatever you typed in the client side (at least one character - an empty string exits the program).

[1] Richard Stevens et al.: UNIX Network Programming, Volume 1, Third Edition: The Sockets Networking API. Section 3.9

--
Gabriel Genellina

Jun 27 '08 #6
En Tue, 17 Jun 2008 14:32:44 -0300, John Salerno <jo******@nospamgmail.comescribió:
"Gabriel Genellina" <ga*******@yahoo.com.arwrote in message
news:ma*************************************@pytho n.org...
>Note that most of the time you want to use the sendall() method, because
send() doesn't guarantee that all the data was actually sent.
<http://docs.python.org/lib/socket-objects.html>

If I use sendall(), am I still recv'ing data with a given buffer size? What
if I send more data than the buffer size. Is my code as written not prepared
to handle that case? It seems like I might need to continue receiving data
until there is no more to receive (in a loop?)...is that right?
send and recv are separate calls (they occur usually in different processes, even in different computers). Buffer sizes are separate too. It is posible to send 5K at once from one side, and require three recv calls on the other side to read it completely. On the other hand, if you try to read from a blocking socket (the default state) when no data is available, the read call will block (and the whole program freezes) until some data is received. There are several alternatives to avoid this, and surely they're explained in detail in a later chapter in your book...

--
Gabriel Genellina

Jun 27 '08 #7
En Tue, 17 Jun 2008 14:32:44 -0300, John Salerno <jo******@nospamgmail.comescribió:
"Gabriel Genellina" <ga*******@yahoo.com.arwrote in message
news:ma*************************************@pytho n.org...
>Note that most of the time you want to use the sendall() method, because
send() doesn't guarantee that all the data was actually sent.
<http://docs.python.org/lib/socket-objects.html>

If I use sendall(), am I still recv'ing data with a given buffer size? What
if I send more data than the buffer size. Is my code as written not prepared
to handle that case? It seems like I might need to continue receiving data
until there is no more to receive (in a loop?)...is that right?
send and recv are separate calls (they occur usually in different processes, even in different computers). Buffer sizes are separate too. It is posible to send 5K at once from one side, and require three recv calls on the other side to read it completely. On the other hand, if you try to read from a blocking socket (the default state) when no data is available, the read call will block (and the whole program freezes) until some data is received. There are several alternatives to avoid this, and surely they're explained in detail in a later chapter in your book...

--
Gabriel Genellina

Jun 27 '08 #8
On Jun 18, 7:52*am, Dennis Lee Bieber <wlfr...@ix.netcom.comwrote:
On Tue, 17 Jun 2008 09:39:07 -0400, "John Salerno"
<johnj...@NOSPAMgmail.comdeclaimed the following in comp.lang.python:
while True:
* *data = raw_input('')
* *if not data:
* * * *break
* *client_socket.send(data)
* *data = client_socket.recv(buffer_size)
* *if not data:
* * * *break
* *print data
client_socket.close()
Also, is that second "if not data: break" statement necessary? It seemslike
once you get past the first if, you don't need the second one. Of course, I
guses it's possible that the server could return a False value, but even
still, would it make sense to break out of the loop and close the connection
because of that?

* * * * The first if is checking for lack of interactive input --and, as
coded, will never break out as ANY response to the prompt will have a
newline attached.
[snip]
FYI, I've just checked:
>>raw_input('')
abc
'abc'

raw_input() doesn't put a newline on the end.
Jun 27 '08 #9
"Dennis Lee Bieber" <wl*****@ix.netcom.comwrote in message
news:vr******************************@earthlink.co m...
The first if is checking for lack of interactive input -- and, as
coded, will never break out as ANY response to the prompt will have a
newline attached.

Try with raw_input("").strip() instead
Well, I know the first if block works properly. Pressing just ENTER will
exit the loop and close the client socket.
The second if is checking for empty receive block... And since
.recv() blocks until it has something to return (as I recall) it may not
be of use...
Interesting point. I'm not sure if it works that way though. I *think* I
tried sending an empty string from the server back to the client, and as
expected it exited the loop and closed the client, which doesn't make sense
to me, since an empty string could be perfectly valid return data.

I opted to remove the second if statement and see where that takes me. :)
Jun 27 '08 #10
Dennis Lee Bieber wrote:
On Wed, 18 Jun 2008 09:56:29 -0400, "John Salerno"
<jo******@NOSPAMgmail.comdeclaimed the following in comp.lang.python:
>Interesting point. I'm not sure if it works that way though. I *think* I
tried sending an empty string from the server back to the client, and as
expected it exited the loop and closed the client, which doesn't make sense
to me, since an empty string could be perfectly valid return data.
Okay... I suppose socket could consider a transmission with 0 data
bytes as valid "data". The main key is that there had to be send of 0
data -- opposed to just not receiving anything..
No, I think you're right. I read elsewhere that when I send() call
returns 0 bytes, the connection is automatically closed.
Jun 27 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Stephan Steiner | last post by:
Hi I have a networking application that periodically needs to go into sleep mode (from an application point of view, I'm simply suspending the receiver thread until it's time to start listening...
0
by: Jack | last post by:
I am trying to develop a simple telnet client in MS.NET I have a small wrapper around the System.Net.Sockets.Socket class which takes care of sending and receiving data and handing it off to a...
13
by: Sharon | last post by:
I'm using TcpClient and getting the Stream by: TcpClient tcpclnt = new TcpClient(); . . . Stream stm = tcpclnt.GetStream(); Now, when I'm trying to send a big buffer via stm.Write(...) I get an...
2
by: Sharon | last post by:
At the TCP server side I'm using: /////////////////////////////////////////////////////////////////////////////// IPAddress DEFAULT_SERVER = IPAddress.Parse("127.0.0.1"); IPEndPoint ipNport =...
2
by: Dirk Reske | last post by:
Hello, does somebody know a good way to code a receivebuffer for a network connection? I receive the bytes asynchronous from a socket! now I want to read all the bytes until a newLine is...
0
by: Christoph Bisping | last post by:
Hello! I'm not sure if this is the right place to ask my question... According to the docs, it is possible to receive udp datagrams asynchronous using the Socket-class and its .BeginRecive(From)...
22
by: semedao | last post by:
Hi , I am using asyc sockets p2p connection between 2 clients. when I debug step by step the both sides , i'ts work ok. when I run it , in somepoint (same location in the code) when I want to...
16
by: Matthew Geyer | last post by:
been using asynchronous sockets with AsyncCallback and System.Net.Sockets as per the excellent MSDN example. everything has been working great, except when i want to receive more total bytes...
10
by: puzzlecracker | last post by:
Say I want to arrange bytes in the internal buffer in a certain way. I receive those bytes in the socket. One solution is to read in socket in pieces: byte buffer = new byte; int index = 0;...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.