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()
Related
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()
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
I'm trying to send a message from Client to Server using socket. For some reason, the message is not received. example: the client sends 'myname_0' the server needs to receive it and decode it and continue further.
Listener:
import socket
class SocketSender():
def __init__(self):
self.sock = socket.socket()
ip = socket.gethostname() # IP to server.
port = 7000
self.sock.bind((ip, port))
print("Binding successful.")
self.sock.listen(2)
print("Listening....")
self.listening = True
# self.sock.connect((ip, port))
# print("Connected.")
def sendpacket(self, packet):
self.sock.send(packet.encode())
def receivepacket(self):
while self.listening:
con, addr = self.sock.accept()
print("Receiving packet from " + str(addr))
packet = self.sock.recv(1024).decode("utf-8")
return str(packet)
Sender:
import socket
sock = socket.socket()
ip = socket.gethostname()
port = 7000
sock.connect((ip, port))
print("connection to " + ip)
message = "test_0"
sock.send(message.encode("utf-8"))
When run:
import GUI
import SocketSender
# Entry: 0, Exit: 1
gui = GUI.ASGui()
# gui.run()
socket = SocketSender.SocketSender()
id = input()
while 1 == 1:
packet = socket.receivepacket()
name, state = packet.split("_")
break
if state == 0:
print("Welcome back, " + name)
else:
if state == 1:
print("Goodbye, " + name)
I do get the outputs Listening and Binded. But I am unable to receive a message. Help would be appreciated. Thank you.
attempting message encryption with a basic client to host connection
client code:
import socket
import datetime
import time
import threading
tLock = threading.Lock()
shutdown = False
def receving(name, sock):
while not shutdown:
try:
tLock.acquire()
while True:
data, addr = socket.recvfrom(1024)
print (str(data))
except:
pass
finally:
tLock.release()
host = '127.0.0.1'
port = 0
server = ('127.0.0.1',5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
s.setblocking(0)
rT = threading.Thread(target=receving, args=("RecvThread",s))
rT.start()
alias = input("Name: ")
IP=int(socket.gethostbyname(socket.gethostname()).replace(".","5"))
time=(int(datetime.datetime.now().strftime("%Y%m%d%H%M%S")))
qw=(int(str((time)+(IP))))
a=int("934")
b=int("346")
c=int("926")
d=int("9522")
e=int("7334")
f=int("5856")
g=int("2432")
h=int("2027")
i=int("7024")
j=int("828")
k=int("798")
m=int("593")
n=int("662")
l=int("5950")
o=int("357")
p=int("506")
q=int("237")
r=int("98")
s=int("372")
t=int("636")
u=int("553")
v=int("255")
w=int("298")
x=int("8822")
y=int("458")
z=int("657")
space=("633")
msg=input("")
msg=msg.replace("a",(str(a)))
msg=msg.replace("b",(str(b)))
msg=msg.replace("c",(str(c)))
msg=msg.replace("d",(str(d)))
msg=msg.replace("e",(str(e)))
msg=msg.replace("f",(str(f)))
msg=msg.replace("g",(str(g)))
msg=msg.replace("h",(str(h)))
msg=msg.replace("i",(str(i)))
msg=msg.replace("j",(str(j)))
msg=msg.replace("k",(str(k)))
msg=msg.replace("m",(str(m)))
msg=msg.replace("n",(str(n)))
msg=msg.replace("l",(str(l)))
msg=msg.replace("o",(str(o)))
msg=msg.replace("p",(str(p)))
msg=msg.replace("q",(str(q)))
msg=msg.replace("r",(str(r)))
msg=msg.replace("s",(str(s)))
msg=msg.replace("t",(str(t)))
msg=msg.replace("u",(str(u)))
msg=msg.replace("v",(str(v)))
msg=msg.replace("w",(str(w)))
msg=msg.replace("x",(str(x)))
msg=msg.replace("y",(str(y)))
msg=msg.replace("z",(str(z)))
msg=msg.replace(" ",(str(space)))
print(msg)
msg=int(msg)
msg=int(msg)*(qw)
print(msg)
fileb=open("key.txt","w")
filec=fileb.write(str(qw))
fileb.close()
file=open("msg decrypt.txt","w")
filea=file.write(str(msg))
file.close()
msg=(str(e)(msg))
print(IP)
print(qw)
if msg != 'q':
if msg != '':
s.sendto(alias.encode() + ": ".encode() + (str(msg).encode)(), server)
tLock.acquire()
msg = input(alias + "-> ")
tLock.release()
shudown = True
rT.join()
s.close()
host code:
import socket
import time
host = '127.0.0.1'
port = 5000
clients = []
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host,port))
s.setblocking(0)
quitting = False
print ("Server Started.")
while not quitting:
try:
data, addr = s.recvfrom(1024)
if "Quit" in str(data):
quitting = True
if addr not in clients:
clients.append(addr)
print (time.ctime(time.time()) + str(addr) + ": :" + str(data))
for client in clients:
s.sendto(data, client)
except:
pass
s.close()
Im struggling as my poor excuse of a encryption is mostly numbers so therefore when im sending using the sendto function only uses str`s or so I think?
either way I get the error:
Traceback (most recent call last):
File "H:\client 2.py", line 103, in <module>
msg=(str(e)(msg))
TypeError: 'str' object is not callable
If msg is an index you should write :
msg = str(e)[msg]
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.