I am new to TCP/IP. I would like to create simple server and client application in Python. I will be using one computer for TCP/IP server and another computer for TCP/IP client. Both computers are Windows based machines.
The server will request the client to send some known data. The server will receive the data from client and confirm each time.
Do we have any demo project on this which could be helpful in the beginning ?
Iâd recommend the book Foundations of Python Network Programming, Third Edition by Brandon Rhodes and John Goerzen for general reading on this topic. Hereâs some of the basic sample programs:
Hereâs the main example of a simple client and server program from the book, saved as udp_local.py:
#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter02/udp_local.py
# UDP client and server on localhost
import argparse, socket
from datetime import datetime
MAX_BYTES = 65535
def server(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('127.0.0.1', port))
print('Listening at {}'.format(sock.getsockname()))
while True:
data, address = sock.recvfrom(MAX_BYTES)
text = data.decode('ascii')
print('The client at {} says {!r}'.format(address, text))
text = 'Your data was {} bytes long'.format(len(data))
data = text.encode('ascii')
sock.sendto(data, address)
def client(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
text = 'The time is {}'.format(datetime.now())
data = text.encode('ascii')
sock.sendto(data, ('127.0.0.1', port))
print('The OS assigned me the address {}'.format(sock.getsockname()))
data, address = sock.recvfrom(MAX_BYTES) # Danger!
text = data.decode('ascii')
print('The server {} replied {!r}'.format(address, text))
if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive UDP locally')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('-p', metavar='PORT', type=int, default=1060, help='UDP port (default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.p)
You can first run the server with python udp_local.py server and then in another terminal window run the client with python udp_local.py client and watch the two programs communicate over UDP packets. This is a simple setup, and the book has a lot more and is worth the read. You can find copies at your library or online if you donât want to purchase one.
Hi, Iâm not sure if this covers exactly what youâre after, but creating a simple server and client were demonstrated in Charles Severanceâs Coursera Course âWeb Application Technologies and Djangoâ (https://www.coursera.org/learn/django-database-web-apps/).
Youâll find in Module 1, there are two Video Lectures, (1) Building a Simple Web Browser in Python (2) Building a Simple HTTP Server in Python. And these lectures demo something similar to what you described. Youâll also find the material earlier in the module covers a lot of the foundations of TCP/IP.
Thank you very much for the example. I am wondering if possible to run both server and client on the same machine ? I mean if server and the client both have same IP address. Would it be possible to run ?
Thank you. I have watched some video tutorials on this subject already. Now I am struggling to run the programs in Python. If you can please point me to simple programs for TCP/IP server and client that would be a great help.
Hi, the (1) and (2) lecture videos I referenced earlier provide âsimple programsâ (including an explainer of the outlined code) that you can use. And yes, these lectures show you how to run both client and server on the same machine, in separate terminals.
Yes, it absolutely is! In fact, thereâs a special IP address that you can use on the client to say âthe serverâs on the same machine as meâ: 127.0.0.1 (or ::1).
I think it is also possible to check the bandwidth/speed of the established link. I mean if we send/receive packets over TCP/IP between server and client, we can run a program to check the speed, right ?
Ahhh, now youâre getting into a tricky area of definition. You absolutely CAN measure speed by sending packets between server and client; in fact, thatâs the ONLY way to measure the actual speed (you might be able to get a nominal speed, but thatâs not your true throughput). HoweverâŚ
Measuring throughput requires that you saturate the connection, to the detriment of all else. If anything else is transferring data, your test will show a figure thatâs too low. (This is a trap that people sometimes fall into while live-streaming - âmy streamâs suffering, maybe I should test the speed RIGHT NOWâ and bam, the stream suffers worse.) And to make matters more confusingâŚ
There are lots of different things you can measure, all with slightly different implications. Most people, when they talk about âspeedâ, are really talking about âthroughputâ. Letâs say you want to download a 1TB file - how long will that take? Divide 1TB by your throughput rate and thatâs how long itâll take. Similarly, you can measure upload throughput. Great! ButâŚ
What about small messages? How long does it take to, say, send out a DNS query and get back a response? This is going to be dominated by latency (ping time), but also can be affected by how you prioritize packets. This doesnât really affect the measured throughput numbers, but it makes a HUGE difference to how snappy the internet âfeelsâ. Which leads us to the final awkwardness:
People FEEL what happens with small messages, but MEASURE what happens with big transfes. If you and your neighbour have internet connections from competing ISPs, and yours measures 22Mbps while your neighbourâs measures 24Mbps, obviously your neighbourâs is better, right? And so ISPs will tend to configure their networks to favour raw throughput, even at the expense of DNS latency. Itâs the difference between having a highway that gets clogged with traffic, and a tram that has a dedicated right-of-way. The highway is moving a lot of cars per hour, and thatâs what everyone measures - but the tram will actually get there efficiently.
So, yes, you absolutely can measure the speed. Just be sure what youâre measuring before you start.
How about if there is a dedicated/separate network card (PIC3 to Ethernet RJ45) installed on the computer. And the network card will be only used to connect Ethernet cable to the Microcontroller board. This way we can test the speed that can reach up to maximum link speed, right ?
Throughput will depend on a lot of factors, but it sounds like you should get pretty much the rated speed, yes. Or rather, if you donât, there would have to be a reason for it.
Ah, donât use that tutorial though, itâs ancient. Find something newer. The socket code wonât be much different, but things like print statements will need to be changed.
Yeah. Python has chosen to organize socket connections in such a way that you connect to a single destination, regardless of the type of socket youâre connecting to. For TCP sockets, the âdestinationâ is a combination of address and port, given as a tuple. So this results in a slightly odd-looking line of code:
s.connect(host, port) # not this
s.connect((host, port)) # this instead
Note that you do the same thing with binding, which you got correct. It looks odd, but it works.
I have two questions. The code is working fine without any problem.
print("This is TCP/IP Echo Server")
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 1255
s.bind((host, port))
s.listen(5)
socketclient, address = s.accept()
print("Got connected form", address)
print("\nListening to TCP/IP Client ... \n")
token = True
while token:
msg = socketclient.recv(1024)
msg = msg.decode("utf-8")
print("TCP/IP Client:", msg)
if msg == "quit":
token = False
s.close()
print("This is TCP/IP Echo Client")
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 1255
s.connect((host, port))
token = True
while token:
msg = input("Enter message send to TCP/IP Server: ")
s.send(msg.encode("utf-8"))
if msg == "quit":
token = False
s.close()
Each time the IP address is the same but the âportâ number is different and is a random number each time. What is the logic ? The IP address remains the same.
Second question: is there anything wrong in socketclient, address = s.accept() which is used in the server program ?
For the most part, source ports in TCP/IP are randomly assigned from a range and only correspond to the particular instance of the running program, not anything else. Theyâre used by the OS as a means of associating which incoming packets should have their data forwarded to which program in memory. When your Python client program sends a request to the server, you want the reply to come back to your program, and not your browser or some other application.