Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How sending and receiving works in Python sockets?

I'm working with python sockets for a while, and I wrote some simple programs.

The problem that I encountered is related to sending/receiving methods in python sockets. Giving you a basic example:

This is the receiver (server):

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 4001))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.listen(5)


while True:
  conn, addr = s.accept()
  print conn, addr

  data1 = conn.recv(64)
  data2 = conn.recv(64)

  print 'uname is %s , password is: %s' %(data1, data2, )
  conn.close()

And this is the sender (or client):

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('', 4001))

uname = raw_input('enter username>')
passw = raw_input('enter password>')

s.send(uname)
s.send(passw)

print 'exiting ...'
s.close()

So the problem is: why server receives both uname and passw in first s.recv() method? It means data2 is always empty!

I have no idea what happens when client executes the s.send() method. I was thinking that each s.send() actually sends a "packet" to the destination (ip, port)!

Can someone explain to me why the second code is working correctly?

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('', 4001))

uname = raw_input('enter username>')
s.send(uname)

passw = raw_input('enter password>')
s.send(passw)

print 'exiting ...'
s.close()
like image 598
Amin Salami Avatar asked Oct 20 '22 08:10

Amin Salami


2 Answers

socket.SOCK_STREAM means you're communicating via TCP . This means, if you call send, your data is pushed to the system's networking stack. Both send calls are called shortly one after another.

If you use TCP, your system decides about the packet size. So the uname and passw might be sent in one packet or even split in any other way.

On the receiver's side, data1 receives up to 64 bytes, which is enough for uname and passw.

The explanation above also shows, why the second one works:

Here you need some time between sending uname and passw. During this time, your OS decides to send the packet (i.e. to flush the network buffer).

When you are using streams, you should not think in terms of packets but in terms of streams. There a send call only means: push some data on my network stack(like a pipeline).

If you are interested in packets, you might try to experiment with UDP:

socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

With such kind of socket your first sender would work as expected

like image 104
ProfHase85 Avatar answered Oct 31 '22 22:10

ProfHase85


I also faced similar problem. Then I implemented a protocol to send and receive one message at a time. Hope this link will help a lot : LINK

like image 25
Mostafiz Rahman Avatar answered Oct 31 '22 20:10

Mostafiz Rahman