Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recv and recvfrom, socket programming using python

Tags:

python

sockets

i am new to python and new to socket programming as well.

I am confused about about socket.recvfrom() and socket.recv()

I understand that usually for UDP, people use recvfrom() and for TCP, people use recv().

For example,

serverSocketUDP = socket(AF_INET, SOCK_DGRAM)
serverSocketTCP = socket(AF_INET, SOCK_STREAM)
#... define server...
#...
message, clientAddress = serverSocketUDP.recvfrom(2048) #why 2048 for UDP? Ive seen several examples like this.
message2 = serverSocketTCP.recv(1024) #Again, why 1024 for TCP? 

As seen in the example above, what i am confused about is the numbers. Why 2048 and 1024 for different protocols? What does these numbers represent? Please explain. I hope i was clear enough. Thank you.

like image 809
user859385 Avatar asked Mar 20 '16 15:03

user859385


People also ask

What is the use of socket Recvfrom () method in Python?

recvfrom(data, address) − This method receives data from the socket. Two pair (data, address) value is returned by this method. Data defines the received data and address specifies the address of socket sending the data.

What is the difference between RECV and Recvfrom?

Unlike the recv() call, which can only be used on a connected stream socket or bound datagram socket, recvfrom() can be used to receive data on a socket whether or not it is connected. If no messages are available at the socket, the recvfrom() call waits for a message to arrive unless the socket is nonblocking.

What is Recvfrom in socket programming?

General description. The recvfrom() function receives data on a socket named by descriptor socket and stores it in a buffer. The recvfrom() function applies to any datagram socket, whether connected or unconnected.


3 Answers

Why 2048 and 1024 for different protocols?

Those are very arbitrary numbers and depend on the protocol being implemented. And even though the TCP number works, the UDP number you give is very likely wrong.

TCP implements a stream protocol that you can read in any sized chunk you want. You could do recv(1) to get a byte at a time or recv(100000) if you want to grab large chunks. recv is free to return smaller blocks that you ask for, so you may get a different size than you want. 1024 is pretty small, you could read much larger chunks without a problem.

UDP implements a message protocol. You have to ask for enough bytes to cover the entire message or it will be dropped. What that size is depends on the protocol. Its common for protocols to limit messages to 1500 (the max size of a standard ethernet packet) but it could be anything up to 65535. Check the actual protocol specs for maximums.

like image 20
tdelaney Avatar answered Oct 14 '22 22:10

tdelaney


You have them switched. TCP sockets should use socket.recv and UDP sockets should use socket.recvfrom. This is because TCP is a connection-oriented protocol. Once you create a connection, it does not change. UDP, on the other hand, is a connectionless ("send-and-forget") protocol. You use recvfrom so you know to whom you should send data back. Recvfrom does not work on TCP sockets the same way.

As for the 1024/2048, these represent the number of bytes you want to accept. Generally speaking, UDP has less overhead than TCP allowing you to receive more data, but this is not a strict rule and is almost negligible in this context. You can receive as much or as little as you would like. 4096 is common as well (for both).

like image 63
Goodies Avatar answered Oct 14 '22 23:10

Goodies


I think people usually use recvfrom for UDP. Because in TCP, once the connection gets established, the address information does not change and hence recvfrom always returns None for connection-information field.

And in the above code, it will error out in this line:

message2, clientAddress2 = serverSocketTCP.recv(1024)

Because: recvfrom() returns (data, connection_information), and recv() returns just the data. So it will raise ValueError because you are trying to unpack a non-tuple value.

1024, or 2048 just defines the buffer size but it does not wait for exactly that much amount of data before returning. For example:

#One side, 'receiver' is a socket
receiver.recv(2048)

#Second side, 'sender' is a socket
sender.send('abc'.encode('utf-8'))

Clearly the data sent by 'sender' is much less than 2048 bytes but the 'recv' call will return immediately after it receives the data sent to it from 'sender'

like image 24
akash12300 Avatar answered Oct 15 '22 00:10

akash12300