Socket is the interface between the application and transport layer.
Port number is a 16-bit integer (0 to 65535) identifier for a socket with IP address. (Note: 0 to 1023 are reserved for standard use. (HTTP service, DNS service etc.)
IP address is an identifier, not for a host but for a network interface. (TBC in IP layer)
2 socket types:
No connection:
Note: The term datagrams is used to refer to data at the IP layer, in transport layer it’s called segments, in application layer, messages. Different terminologies at different layers.
from socket import *
serverName = 'hostname'
serverPort = 12000
# automatically creates random feasible port number for you here.
clientSocket = socket(AF_INET, SOCK_DGRAM)
message = input("input message: ")
# attach server name, port to header and send bytes to server
clientSocket.sendTo(message.encode(), (serverName, serverPort))
# 2048 is the upper limit on the size of the response/buffer size.
response, serverAddress = clientSocket.recvfrom(2048)
print(response.decode())
clientSocket.close()
AF_INET
is the address family for IPv4, SOCK_DGRAM
to specify that we are creating a datagram socket for UDP, not TCP.
Does server not require client info (port number, IP)? No it does! The port number is generated in socket(AF_INET, SOCK_DGRAM)
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET, SOCK_DGRAM)
# bind socket to localhost "", local port number 12000
serverSocket.bind(("", serverPort))
while True:
# clientAddress = (IP address, port number)
msg, clientAddress = serverSocket.recvfrom(2048)
modifiedMessage = message.decode().upper()
serverSocket.sendto(modifiedMessage.encode(), clientAddress)
Note: Binding the port number to the socket is “assigning” anyone who sends a packet to 12000 to this socket. This ensures a fixed port number for senders to request from.
UDP server enters a while loop to receive and process packets. This omits a lot of the burdens that are on the developer to handle:
DNS servers use UDP to send/received requests for IP addresses.
For each client:
The welcoming socket is not the same as the socket for subsequent communicating with the client. Hence there is a three-way handshake.
from socket import *
serverName = 'hostname'
serverPort = 12000
# SOCK_STREAM for stream connection instead of datagrams
clientSocket = socket(AF_INET, SOCK_STREAM)
# connect to establish TCP connection
clientSocket.connect((serverName, serverPort))
message = input("input message: ")
# send won't need to attach server name/port
clientSocket.send(message.encode())
response, serverAddress = clientSocket.recvfrom(2048)
print(response.decode())
clientSocket.close()
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(("", serverPort))
# the welcoming/serverSocket listens for TCP requests
serverSocket.listen(1)
while True:
# server blocks on accept until incoming request is received
# a connectionSocket will be created.
connectionSocket, addr = serverSocket.accept()
message = connectionSocket.recvfrom(2048).decode()
connectionSocket.send(message.upper().encode())
connectionSocket.close()