Created
April 22, 2019 15:40
-
-
Save suyashdamle/1f513fd29aff0c5ef831c2158e349bd2 to your computer and use it in GitHub Desktop.
Joint UDP-TCP client-server programs in Python using Socket Programming
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
HOST = 'localhost' # The server's hostname or IP address | |
PORT = 64532 # The port used by the server | |
use_tcp = False | |
if not use_tcp: | |
################# UDP CLIENT #################### | |
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: | |
# sending data | |
s.sendto(b'Hello, world',(HOST,PORT)) | |
# waiting for response/ACK | |
data,addr = s.recvfrom(1024) | |
else: | |
########### TCP CLIENT ################ | |
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: | |
# connecting to server | |
s.connect((HOST, PORT)) | |
print("Connected to server. Press ENTER to start sending requests") | |
input() | |
# sending data | |
s.sendall(b'Hello, world') | |
# waiting for response/ACK | |
data = s.recv(1024) | |
print('Received', repr(data)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import select | |
import socket | |
import sys | |
import queue | |
HOST = '' #127.0.0.1 Standard loopback interface address (localhost) | |
PORT = 64532 # Port to listen on | |
server_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
server_tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # prevents "already in use" errors | |
server_tcp.setblocking(0) | |
server_tcp.bind((HOST, PORT)) | |
server_tcp.listen(5) | |
server_udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) | |
server_udp.bind((HOST,PORT)) | |
# 3 lists | |
inputs = [server_udp,server_tcp] | |
outputs = [] | |
message_queues = {} # message queue dict | |
while inputs: | |
# the lists get populated with socket objects on select call | |
readable, writable, exceptional = select.select(inputs, outputs, inputs) | |
# select call could unblock if ANY ONE OF THE LISTS is non-empty. So, ... | |
#... (1)there might be a connection request/data coming in... | |
#... (2)or, something to be sent over... | |
#... (3)or, an exception | |
for s in readable: | |
# s is a socket object | |
if s is server_tcp: | |
# for new connections | |
connection, client_address = s.accept() | |
connection.setblocking(0) | |
inputs.append(connection) | |
print("Received connection request from: ",client_address) | |
# creating a message queue for each connection | |
message_queues[connection] = queue.Queue() | |
elif s is server_udp: | |
# if data received over UDP | |
data, addr = s.recvfrom(1024) | |
if data: | |
print("data received over UDP: ", data) | |
data = ("ACK - data received: "+str(data)).encode() | |
s.sendto(data,addr) | |
else: | |
# if some data has been received on TCP connection | |
data = s.recv(1024) | |
if data: | |
print("data received: ",data) | |
# sending back ACK | |
# NOTE: data is in bytes - it has to be sent over the network that way... | |
#... & gets received as bytes as well (notice b" " - type message on client side) | |
data = ("ACK - data received: "+str(data)).encode() | |
message_queues[s].put(data) | |
# add s as a connection waiting to send messages | |
if s not in outputs: | |
outputs.append(s) | |
for s in writable: | |
# If something has to be sent - send it. Else, remove connection from output queue | |
if not message_queues[s].empty(): | |
# if some item is present - send it | |
next_msg = message_queues[s].get() | |
s.send(next_msg) | |
# TODO : is if-else block needed? | |
else: | |
# indicate that server has nothing to send | |
outputs.remove(s) | |
for s in exceptional: | |
# remove this connection and all its existences | |
inputs.remove(s) | |
if s in outputs: | |
outputs.remove(s) | |
s.close() | |
del message_queues[s] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment