a new python coder here.
I am trying to make a game , where there is a 5x5 grid on numbers , and when i click on one of them , they get replaced with a cross 'X' and get greyed out. Here is the code :
import tkinter as tk
from tkinter import *
from tkinter import messagebox
import random
import socket
removed_numbers=[]
def numberClick(num,btn):
messagebox.showinfo('Message',str(num)+' is removed')
removed_numbers.append(num)
btn.configure(text='X')
btn.configure(bg='red',fg='white')
btn.configure(state="disabled")
print(removed_numbers)
root = Tk()
#root.geometry("200x200")
w = Label(root, text='Welcome to Bingo!')
linear_array = [i for i in range(1,26)]
random_array = []
for i in range(1,26):
temp = random.choice(linear_array)
linear_array.remove(temp)
random_array.append(temp)
rows=5
columns=5
btns = [[None for i in range(rows)] for j in range(columns)]
for i in range(rows):
for j in range(columns):
num = random.choice(random_array)
random_array.remove(num)
btns[i][j]=Button(root, text = num , fg ='red',height = 3, width = 5)
btns[i][j]['command']=lambda btn=btns[i][j],num=num: numberClick(num,btn)
btns[i][j].grid(row=i,column=j)
#text1=Text(root,width=47,height=1,bg='grey')
#text1.grid(row=5,column=2)
root.mainloop()
Output here :
Now i want to create a server , where two clients with the same code above connect , and when one button is pressed in a client , the action reflects in the other one as well. I tried to connect the client with server as shown :
Server.py :
import socket
c1 = None #Client socket1
addr1 = None #Client address1
c2 = None #Client socket2
addr2 = None #Client address2
server_socket1 = socket.socket() #by default it is SOCK_STREAM (TCP) and has porotocal AF_INET (IPv4)
server_socket1.bind(('127.0.0.1',9999)) #server machine's ip and port on which it will send and recieve connections from
server_socket1.listen(2) #We will only accept two connections as of now , one for each client
print("Server started successfully!!!")
print("Waiting for connections...\n\n")
flag_client1 = '0'
flag_client2 = '0'
while (((c1 is None)and(addr1 is None)) and ((c2 is None) and (addr2 is None))):
if((c1 is None) and (addr1 is None)):
c1,addr1 = server_socket1.accept()
print("User connected to client1 socket!!")
flag_client1='1'
if((c2 is None) and (addr2 is None)):
c2,addr2 = server_socket1.accept()
print("\n\nUser connected to client2 socket!!")
flag_client2='1'
if(flag_client1=='1' and flag_client2=='1'):
c1.send(bytes(flag_client1,"utf-8"))
c1.send(bytes(flag_client2,"utf-8"))
c2.send(bytes(flag_client1,"utf-8"))
c2.send(bytes(flag_client2,"utf-8"))
while True:
msg = c1.recv(4096)
if(msg!=None):
msg = msg.decode()
c2.send(bytes(msg,"utf-8"))
msg2 = c2.recv(4096)
if(msg2!=None):
msg2 = msg2.decode()
c1.send(bytes(msg2,"utf-8"))
Client.py :
#Connection Part
client_socket = socket.socket() #by default it is SOCK_STREAM (TCP) and has porotocal AF_INET (IPv4)
client_socket.connect(('127.0.0.1',9999)) #server machine's ip and port on which it will send and recieve connections from
But the connection is not getting reflected in server. I know i am wrong here.
Can someone please guide my how can i achieve the mentioned task? Can the same be done with Flask and socketIO? Will it be easy than tkinter? I really need to do it for my UNI project. TIA
Related
I'm writing a program that takes GPU temps and system ID from different systems on a local network and sends it to one main system. I'm having an issue with the receiving part of my program. In my function that accepts the data, I have an infinite loop to continue constantly receiving data from the client system. I also need to take this data out of this function and display it on a tkinter ui. I'm stuck on how to keep the data updating, while also returning it into my GUI
import tkinter as tk
import socket
def startServer():
HOST = socket.gethostname()
PORT = 9999
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print(f"NEW CONNECTION: {addr}")
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
data.decode('utf-8')
data = str(data)
data = data.split(':')
return data[0], data[1]
if __name__ == "__main__":
running = True
window = tk.Tk()
window.geometry('600x600')
button = tk.Button(window, text='Connect', command=startServer)
button.pack()
label = tk.Label(window,text='')
window.mainloop()
running = False
from tkinter import *
import _thread
from typing import TextIO
#页面代码
root = Tk()
root.title('TPC服务端')
root.geometry('640x480')
label_1 = Label(root,relief=GROOVE,text='从客户端接收的数据')
label_1.place(relx=0.1,rely=0.0,relwidth=0.4,relheight=0.1)
Operate = Text(root,relief=GROOVE)
Operate.place(relx=0.1,rely=0.1,relwidth=0.4,relheight=0.4)
Tips = Text(root,relief=GROOVE)
Tips.place(relx=0.1,rely=0.5,relwidth=0.4,relheight=0.4)
Tips.insert(END,'当前状态:\n')
Tips.configure(state=DISABLED)
root.mainloop()
class TCPServer():
def __init__(self):
self.HOST = '192.0.0.1'
self.PORT = 8080
self.BUFSIZ = 1024
self.ADDRESS = (self.HOST,self.PORT)
self.tcpServerSocket = socket(AF_INET, SOCK_STREAM)
self.tcpServerSocket.bind(self.ADDRESS) #IP地址和固定端口信息
self.tcpServerSocket.listen(5)
def try_connect(self):
global var
var='服务器正在运行,等待客户端连接...\n'
Tips.insert(END,var)
Tips.configure(state=DISABLED)
while True:
var='服务器正在运行,等待客户端连接...\n'
Tips.configure(state=NORMAL)
Tips.insert(END,var)
Tips.configure(state=DISABLED)
self.client_socket, self.client_address = self.tcpServerSocket.accept()
var='客户端{}已连接!\n'.format(self.client_address)
Tips.configure(state=NORMAL)
Tips.insert(END,var)
Tips.configure(state=DISABLED)
while True:
self.data = self.client_socket.recv(self.BUFSIZ)
if(self.data):
var='接收到消息 {}({} bytes) 来自 {}\n'.format(self.data.decode('utf-8'), len(self.data), self.client_address)
# 返回响应数据,接受的数据不做处理即返回
self.client_socket.send(self.data)
var='发送消息 {} 至 {}\n'.format(self.data.decode('utf-8'), self.client_address)
Tips.configure(state=NORMAL)
Tips.insert(END,var)
Tips.configure(state=DISABLED)
Operate.configure(state=NORMAL)
Operate.insert(END,self.data)
Operate.configure(state=DISABLED)
else:
var='客户端 {} 已断开!\n'.format(self.client_address)
Tips.configure(state=NORMAL)
Tips.insert(END,var)
Tips.configure(state=DISABLED)
break
# 关闭socket
self.client_socket.close()
# 取消监听socket,自此拒绝响应其它客户端
self.tcpServerSocket.close()
Server = TCPServer()
_thread.start_new_thread(Server.try_connect)
root.mainloop()
![text](enter image description here
I want to know why such a mistake happened.I am using python to make a simple network communication program.It contains both the client and server sides.This is my client program code.
I am a beginner.
The server connects to the client .i use vscode to write the code.I use python 3.10
Hello fellow programmer.
I followed this tutorial https://www.youtube.com/watch?v=QihjI84Z2tQ
Those server and client has successfully connected
but when i try build it did not show the desired output on the client-side terminal.
The server-side terminal does not react anything.
this is my code for server side:
import socket
import numpy as np
import encodings
HOST = '192.168.0.177' # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
def random_data(): # ANY DATA YOU WANT TO SEND WRITE YOUR SENSOR CODE HERE
x1 = np.random.randint(0, 55, None) # Dummy temperature
y1 = np.random.randint(0, 45, None) # Dummy humidigy
my_sensor = "{},{}".format(x1,y1)
return my_sensor # return data seperated by comma
def my_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print("Server Started waiting for client to connect ")
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024).decode('utf-8')
if str(data) == "Data":
print("Ok Sending data ")
my_data = random_data()
x_encoded_data = my_data.encode('utf-8')
conn.sendall(x_encoded_data)
elif str(data) == "Quit":
print("shutting down server ")
break
if not data:
break
else:
pass
if __name__ == '__main__':
while 1:
my_server()
and this is my client code:
import socket
import threading
import time
HOST = '192.168.0.177' # The server's hostname or IP address
PORT = 65432 # The port used by the server
def process_data_from_server(x):
x1, y1 = x.split(",")
return x1,y1
def my_client():
threading.Timer(11, my_client).start()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
my = input("Data")
my_inp = my.encode('utf-8')
s.sendall(my_inp)
data = s.recv(1024).decode('utf-8')
x_temperature,y_humidity = process_data_from_server(data)
print("Temperature {}".format(x_temperature))
print("Humidity {}".format(y_humidity))
s.close()
time.sleep(5)
if __name__ == "__main__":
while 1:
my_client()
I have tried many solution by printing "Data" directly to the terminal.
can anyone help me?
Ok, I have found the problem. I am using Sublime Text 3 when running the client.py script When i post in the build it doesnt response nothing. So I change my IDE to PYCharm and then it worked. I don't know why. I hope that's helpful to other people that have this problem. Thank you very much.
So, I have a server completely written in Python 2.7:
from socket import *
from select import *
HOST = "127.0.0.1"
PORT = 1993
server = socket(AF_INET, SOCK_STREAM)
server.bind((HOST, PORT))
server.listen(5)
clients = []
def getClients():
to_use = []
for client in clients:
to_use.append(client[0])
return to_use
while(True):
read, write, error = select([server],[],[],0)
if(len(read)):
client, address = server.accept()
clients.append([client, address, []])
to_use = getClients()
try:
read, write,error = select(to_use,[],[],0)
if(len(read)):
for client in read:
data = client.recv(1024)
print(bytes.decode(data))
if(data == 0):
for c in clients:
if c[0] == client:
clients.remove(c)
break
else:
for c in clients:
c[2].append(data)
except:
pass
try:
to_use = getClients()
read, write, error = select([], to_use, [], 0)
if(len(write)):
for client in write:
for c in clients:
if c[0] == client:
for data in c[2]:
sent = client.send(data)
if(sent == len(data)):
c[2].remove(data)
break
except:
pass
What I need to do is get constant updates for data (messages) from the
server and print them to a text box made in Tkinter.
The receiving code:
from socket import *
from select import *
HOST = "127.0.0.1"
PORT = 1993
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((HOST, PORT))
while True:
data = bytes.decode(sock.recv(1024))
print data
It doesn't have to be Tkinter, but that's what I have been trying in; as long as it uses a GUI. Don't worry about sending messages I just need to be able to receive the data and print it to the text box/area.
The basic framework is to first create all of the widgets. Next, write a function that reads the data and updates the UI. Finally, arrange to have this function called every few milliseconds.
Roughly speaking, it looks something like this:
import Tkinter as tk
...
class Example(object):
def __init__(self):
self.root = tk.Tk()
self.text = tk.Text(root)
self.text.pack(fill="both", expand=True)
...
def start(self):
self.read_periodically()
self.root.mainloop()
def read_periodically(self):
# read the data
data = bytes.decode(sock.recv(1024))
# update the UI
self.text.insert("end", data)
# cause this function to be called again in 100ms
self.after(100, self.read_periodically)
example = Example()
example.start()
If the data is not a steady stream which causes sock.recv(1024) to block, your UI will freeze while it's waiting for data. If that's the case, you can move the reading of the socket to a thread, and have the thread communicate with the GUI via a thread-safe queue.
If the data is in a steady stream, or you set up a non-blocking socket, you don't have to do any of that.
I wanted to submit a comment first, but give this a try:
You can use something other than a start button to get things going I just put it there for ease of use
from Tkinter import *
import threading
from socket import *
from select import *
master = Tk() #create the GUI window
#put the test program in a seperate thread so it doesn't lock up the GUI
def test_program_thread():
thread = threading.Thread(None, test_program, None, (), {})
thread.start()
def test_program():
HOST = "127.0.0.1"
PORT = 1993
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((HOST, PORT))
while True:
data = bytes.decode(sock.recv(1024))
terminal_listbox.insert(END, str(data))
master.update() #I don't think this line is necessary, but put it here just in case
# set the gui window dimensions and the title on the GUI
master.minsize(width=450, height=450)
master.wm_title("Stack Problem")
# Start button is set to y and starts the test program when hit
start_button = Button(master, text='START', command=test_program_thread)
start_button.place(x=5, y=5)
# scroll bar for the terminal outputs
scrollbar = Scrollbar(master)
scrollbar.place(x=420, y=150)
# Terminal output. Auto scrolls to the bottom but also has the scroll bar incase you want to go back up
terminal_listbox = Listbox(master, width=65, height=13)
terminal_listbox.place(x=5, y=100)
terminal_listbox.see(END)
scrollbar.config(command=terminal_listbox.yview)
#GUI loops here
master.mainloop()
I'm currently working on a project and I need to use socket (python). My problem is :
- When the client disconnect, my server disconnect too. But I don't want this. I want the server to stay alive all the time, how can I do that ?
If I close the client I would like the server to keep alive
Here is my code :
Client :
import socket
hote = "localhost"
port = 12800
connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_avec_serveur.connect((hote, port))
print("Established {}".format(port))
msg_a_envoyer = b""
while msg_a_envoyer != b"fin":
msg_a_envoyer = input("> ")
msg_a_envoyer = msg_a_envoyer.encode()
connexion_avec_serveur.send(msg_a_envoyer)
msg_recu = connexion_avec_serveur.recv(1024)
print(msg_recu.decode())
print("Close connection")
connexion_avec_serveur.close()
Server :
import socket
import select
hote = ''
port = 12800
connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_principale.bind((hote, port))
connexion_principale.listen(5)
print("rece {}".format(port))
serveur_lance = True
clients_connectes = []
while serveur_lance:
connexions_demandees, wlist, xlist = select.select([connexion_principale],
[], [], 0.05)
for connexion in connexions_demandees:
connexion_avec_client, infos_connexion = connexion.accept()
clients_connectes.append(connexion_avec_client)
clients_a_lire = []
try:
clients_a_lire, wlist, xlist = select.select(clients_connectes,
[], [], 0.05)
except select.error:
pass
else:
for client in clients_a_lire:
msg_recu = client.recv(1024)
msg_recu = msg_recu.decode()
print("Recu {}".format(msg_recu))
client.send(b"5 / 5")
if msg_recu == "fin":
serveur_lance = False
Excuse my english.
Thanks for your help
I suspect it's not when the client disconnects, as such, but when the client sends "fin". That's when the client's loop stops, and also when the server's loop stops. The only thing in the code you've posted that changes the value of serveur_lance is when the client sends "fin":
while serveur_lance:
...
if msg_recu == "fin":
serveur_lance = False
So the moment someone types fin into the client, the server will also get the command to stop.
Instead of changing the value of serveur_lance in your server code, you probably want to close that specific connection and remove it from the clients_connectes list.