Multiple TCP connections in python - python

I'm trying to write a server for a chat program. I want the server to have a tcp connection with every chat user. Is there way for the server to have multiple tcp connections at the same time without creating a socket for every connection? And if yes, how?

No. Unlike UDP sockets, TCP sockets work are connection-oriented. Whatever data is written into a socket, "magically" appears to come out of the socket at the other end as a stream of data. For that, both sockets maintain a virtual connection, a state. Among other things, the state defines both endpoints of the conntection - IP and port numbers of both sockets. So a single TCP socket can only talk to a single TCP socket at the other end.
UDP sockets on the other hand operate on a per-packet basis (connectionless), allowing you to send a receive packets to/from any destination using the same socket. However, UDP does not guarantee reliability and in-order delivery.
Btw, your question has nothing to do with python. All sockets (except raw sockets) are operating system sockets that work in the same way in all languages.

Related

How many times is connection_made called for asyncio's create_datagram_endpoint?

Python's asyncio examples show how to create a 'protocol class' for a TCP echo server. The example seems to indicate that these objects spawn for each client connection. In which case: connection_made fires for each new client connection and a 'transport' instance encapsulates a TCP stream socket for the new client.
https://docs.python.org/3/library/asyncio-protocol.html#tcp-echo-server
My question is: to what extent does this behaviour still apply to UDP servers?
My interpretation of the UDP echo server example is that:
There's one UDP listen socket.
UDP is not connection-orientated so there is no need for individual client sockets to be spawned. The same socket is reused for all clients.
Therefore, 'connection_made' would not fire per client. It would fire once, after the server was started.
In which case: this is quite a lot different to how the TCP echo server works since a new object isn't created per client.
https://docs.python.org/3/library/asyncio-protocol.html#udp-echo-server
Is this correct, or am I missing something?

"Join" existing socket in Python

Is it possible to create a socket connection (from either Python or a nc based listener), and then 'join' it from another Python process, sending data from the same socket to the same remote, and vice versa?
It is possible for a Python process to create a listening socket, bind() it to a port, and listen()s for incoming TCP connections on that port, and then at some point after that, another Python process can connect() to that port, at which point the first process can accept() the incoming TCP connection and the two processes can send data to each other over it. So if that is what you are asking about, the Python socket module has the APIs you are looking for.
If OTOH you are asking about splicing a third party in as a middleman between two existing processes that are already communicating with each other over TCP, that is not possible without some serious low-level hackery, since TCP was designed as a 1-to-1 communications mechanism only.

Does a Python 3 TCP Socket have to be connected in order to send data? Or not like UDP?

I want to make a TCP Socket that doesn't connect to the host but instead sends data without connecting... Is that possible with the Python 3 Socket module?
TCP sockets always need to be connected before sending data. Establishing the connection involves an actual packet exchange with the peer, i.e. the TCP 3-way handshake. This is also means that the connect can fail if the target cannot be reached. This is not specific to Python but specific to how TCP sockets work.
With UDP a socket can be connected but does not need to be. Connecting a UDP socket essentially just sets the target on the local socket but does not involve any actual data transfer. This also means that the connect will usually not fail even but a later data transfer might not be able to reach the target.

how to differentiate tcp/udp when programming sockets

Following is a python socket snippet:
import socket
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
My question is: does the line state whethet socket connection will be transported via TCP/IP? So far I was programming TCP connections only, using above line, but probably I was unaware of the fact. Am I able to program UDP connections using python sockets? How can I differentiate the transport layer?
The question isn't strictly connected to python, explanations are welcome as well in c++ or anything else.
The second argument determines the socket type; socket.SOCK_DGRAM is UDP, socket.SOCK_STREAM is a TCP socket. This all provided you are using a AF_INET or AF_INET6 socket family.
Before you continue, perhaps you wanted to go and read the Python socket programming HOWTO, as well as other socket programming tutorials. The difference between UDP and TCP sockets is rather big, but the differences translate across programming languages.
Some information on sockets on the Python Wiki:
UDP Communication
TCP Communication
The general syntax for creating a socket is:
socket(socket_family, socket_type, protocol=0)
We can use either AF_INET (for IPv4) or AF_INET6 (IPv6) as the first argument i.,e for socket_family.
The socket_type is the argument that determines whether the socket to be created is TCP or UDP. For TCP sockets it will be SOCK_STREAM and for UDP it will be SOCK_DGRAM (DGRAM - datagram). Finally, we can leave out the protocol argument which sets it to the default value of 0.
For TCP sockets you should have used bind(), listen() and accept() methods for server sockets and connect() or connect_ex() for client sockets. Whereas for UDP sockets you won't need listen(), accept() and connect() methods (as TCP sockets are connection-oriented sockets while UDP sockets are connection less sockets).
There are specific methods available for UDP to send and receive packets recvfrom() and sendto() respectively while recv() and send() are for TCP. Refer to this documentation for socket for more information on respective methods for TCP and UDP. Also, Core Python Applications Programming by Wesley Chun is a better book for some pretty basics on socket programming.
The main difference is that TCP sockets are connection-based. You can't send or receive anything until you are connected to another TCP socket on the remote machine. Once connected, a TCP socket can only send and receive to/from the remote machine. This means that you'll need one TCP socket for each client in your application.
UDP is not connection-based, you can send and receive to/from anyone at any time with the same socket.

How to check the state of python TCP client socket connected to C TCP server socket?

I'm running tcp server in C and tcp client in python. Both runs in different hardware. Let us consider Hardware A as server and Hardware B as client. If i quit the execution in Hardware A gracefully, it will send a empty packet to client (Hardware B), so that client comes to know connection is disconnected. But instead of quitting directly, i directly power off the Hardware A. Now client (Hardware B) doesn't get notified with empty packet that connection is disconnected. How to handle this scenario ? How does the client know about the disconnection when Hardware A is powered off ?
If the TCP connection is idle, the client won't know for a long time (perhaps never).
If the client is trying to send any data to the server, then the client's TCP packets will stop being acknowledged by the server when the server is powered down; the client's TCP stack will try to resend the packets a few times, but within a couple of minutes it will give up and unilaterally close the TCP socket. At that point the socket will select() ready-for-read, and the next call to read() on the socket will return 0 indicating that the connection is closed.
Therefore if you want to handle this scenario gracefully, the thing to do is periodically send some dummy data on the socket (i.e. something that the server will simply ignore if it receives it). That will be sufficient to ensure that the client's local TCP stack detects and handles the problem.

Categories

Resources