Multi-client server - python

I read a little bit about using select function instead of using threads but I can't understand how to use it in my code.
EDIT:
I tried to run the following code, the program prints "Client connected", but the problem is that it doesn't print "WORKING" which means it will not send data to the client..What's wrong with my code?
import socket
import select
SERVER_PORT = 3000
SERVER_IP = "127.0.0.1"
MESSAGE_START = 3
CONNECTION_LIST = []
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_sock.bind((SERVER_IP, SERVER_PORT))
server_sock.listen(10)
CONNECTION_LIST.append(server_sock)
def broadcast_data (sock, message):
for socket in CONNECTION_LIST:
if socket != server_sock and socket != sock :
try :
socket.send(message)
except :
socket.close()
CONNECTION_LIST.remove(socket)
def main():
while (True):
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])
for sock in read_sockets:
if sock == server_sock:
client_sock, address_sock = server_sock.accept()
CONNECTION_LIST.append(client_sock)
print "Client:"+str(address_sock)+" connected!"
broadcast_data(client_sock,"Welcome to the server")
else:
print "Working:"
ans = ""
while (True):
msg = client_sock.recv(1024)
if (msg == "Hello"):
ans = "Hey"
elif (msg == "QUIT"):
broadcast_data(client_sock,"Bye")
sock.close()
CONNECTION_LIST.remove(sock)
break
else:
ans = "Error!"
broadcast_data(client_sock,ans)
server_sock.close()
main()

Related

How to break while loop when a new message arrives?

I have used Python socket in ESP as a server and Laptop as a client. I customized the socket codes from this site. When I send the loop as the client input, I enter a loop on the server. I don't know how the while loop is broken when I send a word other than loop, For example "Hello".
server.py:
import socket
host = ''
port = 5560
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((host, port))
except socket.error as msg:
print(msg)
print("Socket bind comlete.")
return s
def setupConnection():
s.listen(1)
conn, address = s.accept()
print("Connected to: " + address[0] + ":" + str(address[1]))
return conn
def Hello_():
print('Hello')
def Loop_():
while True:
print('yes')
def dataTransfer(conn):
while True:
data = conn.recv(1024)
data = data.decode('utf-8')
dataMessage = data.split(' ', 1)
command = dataMessage[0]
if command == 'loop':
Loop_()
if command == 'Hello':
Hello_()
else:
print("X")
conn.close()
s = setupServer()
while True:
try:
conn = setupConnection()
dataTransfer(conn)
except:
break
client.py
import socket
host = '192.168.56.1'
port = 5560
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
command = input("Enter your command: ")
s.send(str.encode(command))
s.close()
I know your time is valuable and I appreciate your attention for spending time for help me.
If you want the Loop_() method to return when more data is received on the socket, you can modify the method so that it calls select() to poll the socket to see if more data has arrived, as shown below. (Note that I've added a conn argument to the Loop_() method so I can pass in the socket to check it)
import select
[...]
def Loop_(conn):
while True:
print('yes')
inReady, outReady, exReady = select.select([conn], [], [], 0.0)
if (conn in inReady):
print('more data has arrived at the TCP socket, returning from Loop_()')
break
def dataTransfer(conn):
while True:
data = conn.recv(1024)
data = data.decode('utf-8')
dataMessage = data.split(' ', 1)
command = dataMessage[0]
if command == 'loop':
Loop_(conn)
if command == 'Hello':
Hello_()
else:
print("X")
conn.close()

How to send files in "chunks" by socket?

I'm trying to send a large file (.avi) over socket by sending the content of the file in chunks (a little bit like torrents). The problem is that the script doesn't send the file. I'm out of ideas here.
Any help or twerking of the script would be very appreciated.
Server:
import socket
HOST = ""
PORT = 8050
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
conn, addr = sock.accept()
print("Connected by ", str(addr))
while 1:
data = conn.recv(1024)
if data.decode("utf-8") == 'GET':
with open(downFile,'rb') as output:
l = output.read(1024)
while (l):
conn.send(l)
l = output.read(1024)
output.close()
conn.close()
Client:
import socket
HOST = "localhost"
PORT = 8050
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST,PORT))
while 1:
message = input()
sock.send(bytes(message,'UTF-8'))
conn.send(str.encode('GET'))
with open(downFile, 'wb+') as output:
while True:
rec = str(sock.recv(1024), "utf-8")
if not rec:
break
output.write(rec)
output.close()
print('Success!')
sock.close()
Here are a working client and server that should demonstrate transferring a file over a socket. I made some assumptions about what your code was supposed to do, for example, I assumed that the initial message the client sent to the server was supposed to be the name of the file to download.
The code also includes some additional functionality for the server to return an error message to the client. Before running the code, make sure the directory specified by DOWNLOAD_DIR exists.
Client:
import socket
import sys
import os
HOST = "localhost"
PORT = 8050
BUF_SIZE = 4096
DOWNLOAD_DIR = "downloads"
def download_file(s, down_file):
s.send(str.encode("GET\n" + down_file))
rec = s.recv(BUF_SIZE)
if not rec:
return "server closed connection"
if rec[:2].decode("utf-8") != 'OK':
return "server error: " + rec.decode("utf-8")
rec = rec[:2]
if DOWNLOAD_DIR:
down_file = os.path.join(DOWNLOAD_DIR, down_file)
with open(down_file, 'wb') as output:
if rec:
output.write(rec)
while True:
rec = s.recv(BUF_SIZE)
if not rec:
break
output.write(rec)
print('Success!')
return None
if DOWNLOAD_DIR and not os.path.isdir(DOWNLOAD_DIR):
print('no such directory "%s"' % (DOWNLOAD_DIR,), file=sys.stderr)
sys.exit(1)
while 1:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
except Exception as e:
print("cannot connect to server:", e, file=sys.stderr)
break
file_name = input("\nFile to get: ")
if not file_name:
sock.close()
break
err = download_file(sock, file_name)
if err:
print(err, file=sys.stderr)
sock.close()
Server:
import socket
import sys
import os
HOST = ""
PORT = 8050
BUF_SIZE = 4096
def recv_dl_file(conn):
data = conn.recv(1024)
if not data:
print("Client finished")
return None, None
# Get command and filename
try:
cmd, down_file = data.decode("utf-8").split("\n")
except:
return None, "cannot parse client request"
if cmd != 'GET':
return None, "unknown command: " + cmd
print(cmd, down_file)
if not os.path.isfile(down_file):
return None, 'no such file "%s"'%(down_file,)
return down_file, None
def send_file(conn):
down_file, err = recv_dl_file(conn)
if err:
print(err, file=sys.stderr)
conn.send(bytes(err, 'utf-8'))
return True
if not down_file:
return False # client all done
# Tell client it is OK to receive file
sent = conn.send(bytes('OK', 'utf-8'))
total_sent = 0
with open(down_file,'rb') as output:
while True:
data = output.read(BUF_SIZE)
if not data:
break
conn.sendall(data)
total_sent += len(data)
print("finished sending", total_sent, "bytes")
return True
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
keep_going = 1
while keep_going:
conn, addr = sock.accept()
print("Connected by", str(addr))
keep_going = send_file(conn)
conn.close() # close clien connection
print()
sock.close() # close listener

Python - Can't figure out syntax of tcp/udp client using socket module

I have been trying to make a client-server system following this tutorial and for some reason when testing it on two different computers the two computers won't connect.
Both the UDP and the TCP code have failed, and I suspect it's because I can't figure out which IP goes to where.
Code for host:
import socket
def main():
host = 'ip.ip.ip.ip'
port = 5000
s = socket.socket()
s.bind((host, port))
s.listen(1)
c, addr = s.accept()
print("Connection from: " + str(addr))
while True:
data = c.recv(1024)
if not data:
break
print("From connected user: " + str(data))
data = str(data).upper()
print("Sending " + str(data))
c.send(data)
c.close()
if __name__ == '__main__':
main()
Code for client:
import socket
def main():
host = 'ip.ip.ip.ip'
port = 5000
s = socket.socket()
s.connect((host, port))
message = raw_input("-> ")
while message != 'q':
s.send(message)
data = s.recv(1024)
print("Recived from server: " + str(data))
message = raw_input("-> ")
s.close()
if __name__ == '__main__':
main()

Bad data being received

I am writing a client and server app in Python and I have a problem with received data. In the first "loop" I received good data but in the next "loop" I received bad data. What do I have to do? Maybe you have a better idea to send and receive data.
This is Client:
import socket
import pickle
import sys
host = socket.gethostname()
port = 2004
BUFFER_SIZE = 100000
print("What you want to do:\r1. Select from base\r2.Insert into base")
MESSAGE, MESSAGE1 = input("tcpClientA: Enter message/ Enter exit:").split(",")
tcpClientA = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpClientA.connect((host, port))
while MESSAGE != 'exit':
tcpClientA.send(MESSAGE.encode())
tcpClientA.send(MESSAGE1.encode())
lista=pickle.loads(tcpClientA.recv(BUFFER_SIZE).strip())
print(lista)
print("Variables 1 and 2 are: ", MESSAGE, MESSAGE1)
MESSAGE, MESSAGE1 = input("tcpClientA: Enter message to continue/ Enter exit:").split(",")
tcpClientA.close()
This is Server:
import socket
from threading import Thread
import pyodbc
import pickle
# Multithreaded Python server : TCP Server Socket Thread Pool
class ClientThread(Thread):
def __init__(self,ip,port):
Thread.__init__(self)
self.ip = ip
self.port = port
print ("[+] New server socket thread started for " + ip + ":" + str(port) )
def run(self):
while True :
connsql = pyodbc.connect('DRIVER={SQL Server};SERVER=I7-KOMPUTER\SQLEXPRESS;DATABASE=test')
cursor = connsql.cursor()
data = conn.recv(2048)
#datasplitx, datasplity = data.decode().split(",", 1)
try:
xy = []
xy = data.decode().split(" ")
print("dat: ",data.decode())
print("After del:",xy)
x=str(xy[0])
#y=str(xy[1])
#x, y = [str(x) for x in data.decode().split()]
#y=str(datasplit[1])
#x = str(datasplit[0])
#y = str(datasplit[1])
except ValueError:
print("List does not contain value")
print ("Server received data:", xy)
if x == 'exit':
break
if x == '1':
#if data.decode() == '1':
cursor.execute("select rtrim(name) from client")
rows = cursor.fetchall()
zap=pickle.dumps(rows)
conn.send(zap)
print(pickle.loads(zap))
if x == '2':
#if data.decode() == '2':
cursor.execute("insert into dbo.klient values('"+y+"')")
connsql.commit()
zro=pickle.dumps("Done.")
conn.send(zro)
del xy[:]
print ("cleared list: xy",xy)
# Multithreaded Python server : TCP Server Socket Program Stub
TCP_IP = '0.0.0.0'
TCP_PORT = 2004
BUFFER_SIZE = 1024 # Usually 1024, but we need quick response
tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpServer.bind((TCP_IP, TCP_PORT))
threads = []
while True:
tcpServer.listen(4)
print ("Multithreaded Python server : Waiting for connections from TCP clients...\r" )
(conn, (ip,port)) = tcpServer.accept()
newthread = ClientThread(ip,port)
newthread.start()
threads.append(newthread)
print("Client IP: " +str(ip))
for t in threads:
t.join()

Python Non-blocking peer to peer chat socket.error: [Errno 32] Broken pipe

Hi i write simple chat program for peer to peer chat between server and client.
This code is working for Client side and client can send message and server recives that messages. but for server side when i want to send a message i have error in line 40
File "server.py", line 40, in <module>
newSocket.send('\r<Server>: ' + msg)
socket.error: [Errno 32] Broken pipe
and server crashes.
Server :
import socket
import os
import select
import sys
def prompt():
sys.stdout.write('Server : ')
sys.stdout.flush()
try:
newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
newSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except:
print 'socket Error'
sys.exit(1)
newSocket.bind(('127.0.0.1', 8000))
newSocket.listen(5)
input_list = [newSocket, sys.stdin]
print 'Chat Program'
prompt()
while True:
inputready, outputready, exceptready = select.select(input_list,[],[])
for sock in inputready:
if sock == newSocket:
(client, (ip, port)) = newSocket.accept()
input_list.append(client)
data = client.recv(2048)
if data:
sys.stdout.write(data)
elif sock == sys.stdin:
msg = sys.stdin.readline()
newSocket.send('\r<Server>: ' + msg)
prompt()
else:
data = sock.recv(2048)
if data:
sys.stdout.write(data)
newSocket.close()
client :
import socket
import os
import select
import sys
def prompt():
sys.stdout.write('Client ')
sys.stdout.flush()
try:
newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
newSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except:
print 'socket Error'
sys.exit(1)
newSocket.connect(('127.0.0.1', 8000))
print 'Connected to remote host. Start sending messages'
prompt()
while 1:
socket_list = [sys.stdin, newSocket]
read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [])
for sock in read_sockets:
if sock == newSocket:
data = sock.recv(4096)
if not data:
print '\nDisconnected from chat server'
sys.exit()
else:
sys.stdout.write(data)
prompt()
else:
msg = sys.stdin.readline()
newSocket.send('\r<Client>: ' + msg)
prompt()
You should use accept(). It seems newSocket is not ready to output when you try to .send() with it.
I change Server code to this and problem has been solved:
import socket
import select
import sys
CONNECTION_LIST = []
RECV_BUFFER = 4096
PORT = 1245
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('0.0.0.0', PORT))
server_socket.listen(5)
CONNECTION_LIST.append(server_socket)
CONNECTION_LIST.append(sys.stdin)
print 'Chat server Started on port ' + str(PORT)
def broadcast_data(sock, message):
for socket in CONNECTION_LIST:
if socket != server_socket and socket != sock and socket != sys.stdin:
try:
socket.send(message)
except:
socket.close()
CONNECTION_LIST.remove(socket)
def prompt() :
sys.stdout.write('<You> ')
sys.stdout.flush()
prompt()
while True:
read_sockets, write_sockets, error_sockets = select.select(CONNECTION_LIST, [], []) # NON_blocking I/O with 0
for sock in read_sockets:
if sock == server_socket:
# new Connection
sockfd, addr = server_socket.accept()
CONNECTION_LIST.append(sockfd)
print 'Clinet (%s, %s) connected ' % addr
broadcast_data(sockfd, "[%s:%s] entered room" % addr)
elif sock == sys.stdin:
msg = sys.stdin.readline()
broadcast_data(sock, 'Server > ' + msg)
prompt()
else:
try:
#In Windows, sometimes when a TCP program closes abruptly,
# a "Connection reset by peer" exception will be thrown
data = sock.recv(RECV_BUFFER)
if data:
print "\r" + '<' + str(sock.getpeername()) + '>' + data
broadcast_data(sock, "\r" + '<' + str(sock.getpeername()) + '>' + data)
except:
broadcast_data(sock, "Client (%s, %s) is offline" % addr)
print "Client (%s, %s) is offline" % addr
sock.close()
CONNECTION_LIST.remove(sock)
continue

Categories

Resources