Python client socket not receiving data from TCP server - python

I'm trying to build a fake money transfer program with sockets in python. Everything is working perfectly except the "name" and "amount" transfer from the server to the client. When someone clicks receive on the client interface, the server is supposed to send the client the name of the person who sent the money and the amount. The problem is that the client is not receiving the data sent from the server. When you click the "receive" button, the interface just freezes then crashes. From the debugging I've done, I'm pretty sure the server is sending the name and amount, but the client is not receiving it. I honestly have no idea why it's not working. Everything I did should work like it has numerous other times throughout the program. This one has got me stumped.
Any help would be great. Thanks! 😁
[CODE]
Server.py:
import socket
import threading
HOST = '192.168.1.6'
PORT = 9090
def client_fun(client, addr):
global transfers
print(f"{addr} just connected!")
connected = True
while connected:
msg = client.recv(1024).decode('utf-8')
if msg == "RECEIVE_CHECK":
usrn = client.recv(1024).decode('utf-8')
transfers_ = open("transfers.txt", "r")
transfers = str(transfers_.readlines())
transfers = transfers.split("+")
transfers[0] = transfers[0].replace("[", "")
transfers[0] = transfers[0].replace("'", "")
transfers.pop()
names = []
for tran in transfers:
tran_ = tran.split("-")
i = 0
while i <= len(tran):
names.append(tran_[2])
i += 1
if usrn in names:
client.send("OK".encode('utf-8'))
else:
client.send("NO".encode('utf-8'))
if usrn in names:
for tran in transfers:
tran_ = tran.split("-")
if usrn == tran_[2]:
name = str(tran_[0])
amount = str(tran_[1])
client.send(name.encode('utf-8'))
client.send(amount.encode('utf-8'))
account_file = usrn + "_" + "account.txt"
account_r = open(account_file, "r")
account_r = str(account_r.readlines())
account_r = account_r.replace(']', '')
account_r = account_r.replace('[', '')
account_r = account_r.replace("'", "")
try:
account_r = int(account_r)
except:
print("Can't Convert Str to Int!")
break
new_amount = int(tran_[1]) + account_r
account_w = open(account_file, "w")
account_w.write(str(new_amount))
account_w.close()
tran = tran + "+"
transFers_ = open("transfers.txt", "r")
transFers = str(transFers_.readlines())
transFers_.close()
transFers = transFers.replace(']', '')
transFers = transFers.replace('[', '')
transFers = transFers.replace("'", "")
transFers = transFers.replace(tran, '')
transFers_ = open("transfers.txt", 'w+')
transFers_.write(transFers)
transFers_.close()
print("Excepted!")
else:
print("Nothing Here!")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
print("Server is listening!")
while True:
c_socket, address = server.accept()
thread = threading.Thread(target=client_fun, args=(c_socket, address))
thread.start()
Client.py:
import socket
HOST = '192.168.1.6'
PORT = 9090
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def receive(usrn):
socket.send("RECEIVE_CHECK".encode('utf-8'))
socket.send(usrn.encode('utf-8'))
c = socket.recv(1024).decode('utf-8')
if c == "OK":
try:
print("Trying to except....")
name = socket.recv(2000).decode('utf-8')
amount = socket.recv(2000).decode('utf-8')
print("Excepted!")
messagebox.showwarning("Continue?", f"{name} has sent you ${amount}", icon="question")
messagebox.showwarning("Info", f"${amount} has just been transferred to your account!", icon="info")
menu(usrn)
except:
print("Error!")
else:
print("Nothing Today!")

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()

Execute a functions remotely with python 3

I am pretty new to python and I had a script idea:
You have a listener which is waiting for functions and a client script which sends instructions to the server and in this case instructions are functions.
Like that I could execute functions code from the client on the other computer
I tried pickle but I can't figure out if it's working with functions
Shall I use Sockets or something else ?
here is the server code:
import socket
import time
HEADER_LENGHT = 10
IP = socket.gethostname()
PORT = 1234
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((IP, PORT))
s.listen(5)
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established ! ")
while True:
full_msg = b''
new_msg = True
while True:
msg = s.recv(16)
if new_msg:
print(f"New message lenght: {msg[:HEADERSIZE]}")
msglen = int(msg[:HEADERSIZE])
new_msg = False
full_msg += msg
if len(full_msg)- HEADERSIZE == msglen:
print("full msg recvd")
print(full_msg[HEADERSIZE:])
d = pickle.loads(full_msg[HEADERSIZE:])
print(d)
new_msg = True
full_msg = b''
print(full_msg)
The client code :
import socket
HEADERSIZE = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1235))
while True:
full_msg = b''
new_msg = True
while True:
msg = s.recv(16)
if new_msg:
print(f"New message lenght: {msg[:HEADERSIZE]}")
msglen = int(msg[:HEADERSIZE])
new_msg = False
full_msg += msg.decode("utf-8")
if len(full_msg)- HEADERSIZE == msglen:
print("full msg recvd")
print(full_msg[HEADERSIZE:])
new_msg = True
full_msg = b''
print(full_msg)
Here is the function code:
def generate(target, apikey, nbfriendly, nbteacher, nbleader, accounts):
acc_list = accounts
jsonFile = open("config.json", "r")
data = json.load(jsonFile)
lines_count = 0
if nbfriendly == "":
nbfriendly = 10
if nbteacher == "":
nbteacher = 10
if nbleader == "":
nbleader = 10
if apikey == "":
apikey = (data['steamWebAPIKey'])
if target == "":
target = (data['target'])
for l in accounts:
lines_count = lines_count + 1
conn = sqlite3.connect("accounts.sqlite")
c = conn.cursor()
max = accounts.count("\n")
counter = 0
print(accounts)
accounts = accounts.replace(":", " ")
accounts = accounts.replace("\n", " ")
accounts.split()
print(accounts)
splitted = accounts.split()
while counter < max:
username = splitted[counter]
password = splitted[(counter + 1)]
c.execute(
"INSERT INTO accounts (username, password, sharedSecret, lastCommend, operational) VALUES (? , ?, ?, ? , ?)",
(username, password, blank, mone, one)
)
conn.commit()
counter += 2
nbfriendly = int(nbfriendly)
nbteacher = int(nbteacher)
nbleader = int(nbleader)
target = str(target)
(data['commend']['friendly']) = nbfriendly
(data['commend']['teaching']) = nbteacher
(data['commend']['leader']) = nbleader
(data['target']) = target
(data['steamWebAPIKey']) = apikey
data = json.dumps(data, indent=4)
jsonFile.close()
with open('config.json', 'w') as outfile:
outfile.write(data)
outfile.close()
I'm not sure your code for sending messages using socket is correct (I don't see where you're sending bytes).
Concerning pickle is is indeed possible to use it as a function. Plus, the good thing is that it is dumped as a bytes object, so you don't even need to cast it before sendding it with sockets.
On the client side:
import pickle
def f(n):
return n * f(n - 1) if n else 1
to_send = pickle.dumps(f)
# Send to_send using sockets then
Then, on the server side, the only thing you need is to load the function:
import pickle
f = pickle.loads(received)
Since everything is an object in Python, you can use the exact same method to send the function's arguments using sockets and pickle.

Python multiple clients chatting across a server

The server is not broadcasting the sent messages back to the clients. The server is also not seeing the messages but is seeing that there is something being sent via the broadcast. The client who sends the message should not be sent the message again.
ChatClient
import socket, threading
def send():
while True:
msg = raw_input('\nMe : ')
cli_sock.send(msg)
def receive():
while True:
sen_name = cli_sock.recv(1024)
data = cli_sock.recv(1024)
print('\n' + str(sen_name) + ' : ' + str(data))
if __name__ == "__main__":
# socket
cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect
HOST = 'localhost'
PORT = 5023
cli_sock.connect((HOST, PORT))
print('Connected to remote host...')
uname = raw_input('Enter your name to enter the chat : ')
cli_sock.send(uname)
thread_send = threading.Thread(target = send)
thread_send.start()
thread_receive = threading.Thread(target = receive)
thread_receive.start()
ChatServer
import socket, threading
def accept_client():
while True:
#accept
cli_sock, cli_add = ser_sock.accept()
uname = cli_sock.recv(1024)
CONNECTION_LIST.append((uname, cli_sock))
print('%s is now connected' %uname)
thread_client = threading.Thread(target = broadcast_usr, args=
[uname, cli_sock])
thread_client.start()
def broadcast_usr(uname, cli_sock):
while True:
try:
data = cli_sock.recv(1024)
if data:
print "{0} spoke".format(uname)
b_usr(cli_sock, uname, data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, sen_name, msg):
for client in CONNECTION_LIST:
if client[1] != cs_sock:
client[1].send(sen_name)
client[1].send(msg)
if __name__ == "__main__":
CONNECTION_LIST = []
# socket
ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind
HOST = 'localhost'
PORT = 5023
ser_sock.bind((HOST, PORT))
# listen
ser_sock.listen(1)
print('Chat server started on port : ' + str(PORT))
thread_ac = threading.Thread(target = accept_client)
thread_ac.start()
The expected should be if user is Dan(me):
John: Hi
Me: Hi
Me: How are you
John: Great
Stephen: Awesome
The actual is only displaying the "Me" on the specific client's side

Creating a simple Chat application in Python (Sockets)

I'm trying to create a simple chat application using sockets (python). Where a client can send a message to server and server simply broadcast the message to all other clients except the one who has sent it.
Client has two threads, which are running forever
send: Send simply sends the cleints message to server.
receive: Receive the message from the server.
Server also has two threads, which are running forever
accept_cleint: To accept the incoming connection from the client.
broadcast_usr: Accepts the message from the client and just broadcast it to all other clients.
But I'm getting erroneous output (Please refer the below image). All threads suppose to be active all the times but Some times client can send message sometimes it can not. Say for example Tracey sends 'hi' 4 times but its not broadcasted, When John says 'bye' 2 times then 1 time its message gets braodcasted. It seems like there is some thread synchronization problem at sever, I'm not sure. Please tell me what's wrong.
Below is the code.
chat_client.py
import socket, threading
def send():
while True:
msg = raw_input('\nMe > ')
cli_sock.send(msg)
def receive():
while True:
sen_name = cli_sock.recv(1024)
data = cli_sock.recv(1024)
print('\n' + str(sen_name) + ' > ' + str(data))
if __name__ == "__main__":
# socket
cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect
HOST = 'localhost'
PORT = 5023
cli_sock.connect((HOST, PORT))
print('Connected to remote host...')
uname = raw_input('Enter your name to enter the chat > ')
cli_sock.send(uname)
thread_send = threading.Thread(target = send)
thread_send.start()
thread_receive = threading.Thread(target = receive)
thread_receive.start()
chat_server.py
import socket, threading
def accept_client():
while True:
#accept
cli_sock, cli_add = ser_sock.accept()
uname = cli_sock.recv(1024)
CONNECTION_LIST.append((uname, cli_sock))
print('%s is now connected' %uname)
def broadcast_usr():
while True:
for i in range(len(CONNECTION_LIST)):
try:
data = CONNECTION_LIST[i][1].recv(1024)
if data:
b_usr(CONNECTION_LIST[i][1], CONNECTION_LIST[i][0], data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, sen_name, msg):
for i in range(len(CONNECTION_LIST)):
if (CONNECTION_LIST[i][1] != cs_sock):
CONNECTION_LIST[i][1].send(sen_name)
CONNECTION_LIST[i][1].send(msg)
if __name__ == "__main__":
CONNECTION_LIST = []
# socket
ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind
HOST = 'localhost'
PORT = 5023
ser_sock.bind((HOST, PORT))
# listen
ser_sock.listen(1)
print('Chat server started on port : ' + str(PORT))
thread_ac = threading.Thread(target = accept_client)
thread_ac.start()
thread_bs = threading.Thread(target = broadcast_usr)
thread_bs.start()
Ok I lied in my comment earlier, sorry. The issue is actually in the broadcast_usr() function on the server. It is blocking in the recv() method and preventing all but the currently selected user from talking at a single time as it progresses through the for loop. To fix this, I changed the server.py program to spawn a new broadcast_usr thread for each client connection that it accepts. I hope this helps.
import socket, threading
def accept_client():
while True:
#accept
cli_sock, cli_add = ser_sock.accept()
uname = cli_sock.recv(1024)
CONNECTION_LIST.append((uname, cli_sock))
print('%s is now connected' %uname)
thread_client = threading.Thread(target = broadcast_usr, args=[uname, cli_sock])
thread_client.start()
def broadcast_usr(uname, cli_sock):
while True:
try:
data = cli_sock.recv(1024)
if data:
print "{0} spoke".format(uname)
b_usr(cli_sock, uname, data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, sen_name, msg):
for client in CONNECTION_LIST:
if client[1] != cs_sock:
client[1].send(sen_name)
client[1].send(msg)
if __name__ == "__main__":
CONNECTION_LIST = []
# socket
ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind
HOST = 'localhost'
PORT = 5023
ser_sock.bind((HOST, PORT))
# listen
ser_sock.listen(1)
print('Chat server started on port : ' + str(PORT))
thread_ac = threading.Thread(target = accept_client)
thread_ac.start()
#thread_bs = threading.Thread(target = broadcast_usr)
#thread_bs.start()
I tried to get around the bug you said #Atinesh. The client will be asked a username once and this 'uname' will be included in the data to be sent. See what I did to the 'send' function.
For easier visualization, I added a '\t' to all received messages.
import socket, threading
def send(uname):
while True:
msg = raw_input('\nMe > ')
data = uname + '>' + msg
cli_sock.send(data)
def receive():
while True:
data = cli_sock.recv(1024)
print('\t'+ str(data))
if __name__ == "__main__":
# socket
cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect
HOST = 'localhost'
PORT = 5023
uname = raw_input('Enter your name to enter the chat > ')
cli_sock.connect((HOST, PORT))
print('Connected to remote host...')
thread_send = threading.Thread(target = send,args=[uname])
thread_send.start()
thread_receive = threading.Thread(target = receive)
thread_receive.start()
You also have to modify your server code accordingly.
server.py
import socket, threading
def accept_client():
while True:
#accept
cli_sock, cli_add = ser_sock.accept()
CONNECTION_LIST.append(cli_sock)
thread_client = threading.Thread(target = broadcast_usr, args=[cli_sock])
thread_client.start()
def broadcast_usr(cli_sock):
while True:
try:
data = cli_sock.recv(1024)
if data:
b_usr(cli_sock, data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, msg):
for client in CONNECTION_LIST:
if client != cs_sock:
client.send(msg)
if __name__ == "__main__":
CONNECTION_LIST = []
# socket
ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind
HOST = 'localhost'
PORT = 5023
ser_sock.bind((HOST, PORT))
# listen
ser_sock.listen(1)
print('Chat server started on port : ' + str(PORT))
thread_ac = threading.Thread(target = accept_client)
thread_ac.start()
The things that changed in the server side are: the user who connected and the user who spoke is not seen anymore. I don't know if it would mean that much if your purpose is to connect clients. Maybe if you want to strictly monitor clients via the server, there could be another way.

Receive more than one message on more than one port Echo Server python

I am writing a echo server and client in Python, that implements a simple number guessing game. I know how to multiplex using select, that's fine. The other server I wrote achieves this. But now I am writing a new server (which is fairly similar), however it accepts connections from two ports rather than one, one port for player client, and one for admin which I will use eventually for the who command, returning all connected players.
My problem is, that after sending the initial greetings message, the clients receive feedback from the server on the first send, recv. But after that I cannot send any more messages to server (nothing gets sent from the clients), I have been searching and playing around for hours, to no avail. Any help would be appreciated. Thanks!
# MULTIPLEX SERVER
import socket, select, time, random, ssl, sys, os
# VARS
EXP = 1
HOST = '127.0.0.1'
PORT_P = 4000
PORT_A = 4001
BUFFSZ = 1024
BKLOG = 5
GREETS = 'Greetings'
INPUTS = []
OUTPUTS = []
CLIENT_ADDRS = {}
CLIENT_ANS = {}
CLIENTS = ""
_adm_rtnMSG = 'Admin_Greetings'
# Function to determine how far the player is
# from the chosen random number
def Within(value, target):
diff = abs(target - value)
if diff > 3:
return 'Not even close, youth!'
else:
return 'Ooh, not to far: ' + str(diff) + ' away, keep trying...'
# END_FUNCTION
print('Server up and running...\n')
try:
for p in PORT_P, PORT_A:
INPUTS.append(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
INPUTS[-1].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
INPUTS[-1].bind((HOST, p))
INPUTS[-1].listen(BKLOG)
except socket.error(value, message):
if INPUTS[-1]:
INPUTS[-1].close()
INPUTS = INPUTS[:-1]
print('Failure to open socket: ' + message)
sys.exit(1)
while True:
READ_IO, WRITE_IO, ERROR = select.select(INPUTS, OUTPUTS, INPUTS)
for r in READ_IO:
for p in INPUTS:
if r is p:
(acpt_sock, addr) = p.accept()
print('Connection established with ', acpt_sock.getsockname())
CLIENT_ADDRS[acpt_sock] = addr
CLIENT_ANS[acpt_sock] = random.randrange(1, 20)
else:
data = acpt_sock.recv(BUFFSZ).decode()
acpt_sock.setblocking(0)
if data:
if 'Hello' in data:
print(CLIENT_ADDRS[acpt_sock], ' random number is: ', CLIENT_ANS[acpt_sock])
acpt_sock.send(b'Greetings\nGuess a random number between 1 & 20')
# drop elif here for admin cmd
elif 'Hi' in data:
acpt_sock.send(_adm_rtnMSG.encode())
else:
if int(data) == CLIENT_ANS[acpt_sock]:
acpt_sock.send(b'That was correct, Well done!')
else:
acpt_sock.send(str(Within(int(data), CLIENT_ANS[acpt_sock])).encode())
else:
print('Closing Connection # ', addr)
INPUTS.remove(acpt_sock)
acpt_sock.close()
del CLIENT_ADDRS[acpt_sock]
# PLAYER CLIENT
import socket
import re
# INIT VARS
HOST = '127.0.0.1'
PORT = 4000
INITSTR = 'Hello'
BUFF = 1024
# Set up socket
sender = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sender.connect((HOST, PORT))
sender.send(bytes((INITSTR), "ascii"))
print("Kirby Prompt FTW!\nConnected to Server via", HOST, "::", PORT, '\n')
rtnMSG = sender.recv(BUFF).decode()
print(rtnMSG)
# Simple loop to keep client alive
# to send and receive data from the server
while 'correct' not in rtnMSG:
_guess = input("(>',')> ")
sender.send(bytes((_guess), "ascii"))
rtnMSG = sender.recv(BUFF).decode()
print(rtnMSG)
sender.close()
# ADMIN CLIENT
import socket
import re
import ssl
# INIT VARS
HOST = '127.0.0.1'
PORT = 4001
INITSTR = 'Hi'
BUFF = 1024
# Set up socket
adm_sender = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
adm_sender.connect((HOST, PORT))
adm_sender.send(bytes((INITSTR), "ascii"))
print("Connected to Server as Admin via", HOST, "::", PORT, '\n')
rtnMSG = adm_sender.recv(BUFF).decode()
print(rtnMSG)
while True:
cmd = input('$ ')
adm_sender.send(bytes((cmd), "ascii"))
rtnMSG = adm_sender.recv(BUFF).decode()
print(rtnMSG)
adm_sender.close()

Categories

Resources