Tkinter socket sending data error while opening the server and client - python

Got an error of: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied when using socket with tkinter on login between server and client
Server :
import socket
import pickle
import datetime
# Socket settings
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # socket setting
my_socket.bind(('0.0.0.0', 1024)) # binding the server ip
my_socket.listen(10) # how much people can join the server
client_socket, client_address = my_socket.accept() # accepting the people if the server is available
print("Server Open") # prints that the server is open
# Functions
def get_users():
# get from the login_users.txt all users & passwords
# format in file - username|password
logs = []
with open('login_users.txt', 'r') as f:
for line in f:
cur = line.strip('\n\r')
cur = cur.split("|")
logs.append(cur)
f.close()
return logs
def get_rank(user):
# get from the ranks.txt all users & passwords
# format in file - username|password
ranks = []
with open('ranks.txt', 'r') as f:
for line in f:
cur = line.strip('\n\r')
cur = cur.split("|")
ranks.append(cur)
f.close()
for r in ranks:
if r[0] == user:
return r[1]
def add_to_logs(user, line):
# add attempt to record (logs_.txt)
now = datetime.datetime.now()
with open('logs_.txt', 'a') as f:
f.write(line + " " + str(now) + "\n")
f.close()
def user_exist(user):
for log in logs:
if log[0] == user:
return True
def check(user, password):
# check the password that the user typed
# if there are 3 failed tried disable the login button
global logs
global atmp
global null_state
global login_state
global logged_user
global status
# get text from boxes:
user = user.get()
password = password.get()
print("user: ", user)
print("pass: ", password)
# add attempt to logs_ file
add_to_logs(user, f"{user} has tried to log in.")
atmp += 1
if user_exist(user):
null_state = False
for log in logs:
if log[0] == user and log[1] == password:
# pop up login succeed
login_state = True
logged_user = user
status = True
if __name__ == '__main__':
btpressed = pickle.loads(my_socket.recv(1024))
if btpressed:
client_socket.send(pickle.dumps([status]))
username, password = pickle.loads(my_socket.recv(1024)) # Getting data from the server
status = check(username, password)
print(status)
client:
import socket
import pickle
import tkinter as tk
import tkinter.messagebox as mb
import tkinter.font as tkFont
user_send = "nothing"
pass_send = "nothing"
# Socket settings
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # setting the socket
my_socket.connect(('127.0.0.1', 1024)) # joining the server
print("Connected to the server successfully!")
def check_null(user, password):
global null_state
# check for the username and password in the file:
if user == "" or password == "" or user == "" and password == "":
null_state = True
fail_msg = "Please make sure you have entered username and password in both fields!"
mb.showinfo(title="Enter username and password", message=fail_msg)
#def display_system():
#root1.title("Secure4U")
#root1.geometry("1200x600")
#fontStyle = tkFont.Font(family="Lucida Grande", size=20)
#show_user_logged = tk.Label(root1, text="Hello " + logged_user + ",", font=fontStyle)
#show_user_logged.pack(side="top", anchor="nw")
#user_rank =
#show_user_rank = tk.Label(root1, text="Rank: " + str(user_rank), font=fontStyle)
#show_user_rank.pack(side="top", anchor="nw")
#root1.mainloop() # run tkinter display
def display_login():
global log_button
# initiate and display all objects on screen
root.title("Secure4U Login")
root.geometry("450x250")
fontStyle = tkFont.Font(family="Lucida Grande", size=20)
# user name
user_label = tk.Label(root, text="Username:", font=fontStyle)
# user_box = tk.Text(root, bg="grey", height=1, width=20, font=fontStyle)
user_box = tk.Entry(root, bg="grey", font=fontStyle)
user_label.pack()
user_box.pack()
# password
pass_label = tk.Label(root, text="Password:", font=fontStyle)
# pass_box = tk.Text(root, bg="grey", font=fontStyle)
pass_box = tk.Entry(root, bg="grey", font=fontStyle, show="*")
pass_label.pack()
pass_box.pack()
# login button
log_button = tk.Button(root, text='Login', height=2, width=20, command=lambda:(button_pressed()))
log_button.pack()
user_send = user_box
pass_send = pass_box
root.mainloop() # run tkinter display
def button_pressed():
BtPressed = True
if __name__ == '__main__':
global BtPressed
BtPressed = False
status = False
my_socket.send(pickle.dumps([BtPressed]))
if not status:
null_state = False # checks if the user entered null data on one or both of the fields
root = tk.Tk()
display_login()
if BtPressed:
my_socket.send(pickle.dumps([user_send, pass_send])) # Sending data to the server
status = pickle.loads(my_socket.recv(1024)) # Getting data from the server
# success_msg = f"Hello {logged_user}, you logged in successfully!"
# mb.showinfo(title="login succeed!", message=success_msg)
I don't know what it happened and I tried everything, please help me if you can
Thank you :)

Related

Decoding data sent through a TCP socket in Python

I have a basic program where in a Tkinter window a user presses a button that generates a string in a listbox. Using a second send button, I want to transfer those strings through a socket server to a second client. The message printed to the console at the point of departure (client1) is a tuple, and it can be iterated through with a for loop to make it more legible i.e. each element is printed to a new line. Using a print function at the point of arrival (client2), the same tuple is produced, but trying to use a for loop on it iterates through each character in the group of strings, as opposed to each element of the tuple as desired.
This is client1:
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
from tkinter import messagebox
from tkinter import scrolledtext
from tkinter import ttk
from tkinter import font
import os
import datetime
import pickle
def receive():
while True:
try:
msg = client_socket.recv(BUFSIZ).decode("utf8")
except OSError: # Possibly client has left the chat.
break
def send(event=None): # event is passed by binders.
global sent
global current_datetime
global order_list
sent = order_list.get(0, END)
msg = sent
for i in msg:
print(i)
client_socket.send(bytes(str(msg), "utf8"))
if msg == "{quit}":
client_socket.close()
window.quit()
order_list.delete(0, END)
window = tkinter.Tk()
window.title("Title")
window.geometry("1280x1080")
var = IntVar()
var.set(1)
check_Table_Button = False
font = font.Font(family="Arial", size=9, weight="bold")
height = 4
width = 7
padx = 8
pady = 1
order_list=Listbox(window, width=35, height = 35)
order_list.config(font=font)
order_list.grid(row =0, column = 11, columnspan=3, rowspan=8)
def clickedTable(table):
# print(table)
order_list.insert(END, table)
global check_Table_Button
check_Table_Button = True
def addTable(table, number, x) #Sample Button to generate string
table = table
btn_masa_x = Button(window, text=str(table),font=font,
bg="orange", fg="black",
command=lambda: clickedTable(table),
height=height, width=width,
padx=padx+1, pady=pady)
btn_masa_x.grid(column=x, row=number, rowspan=1, columnspan=1)
addTable("Table 1 ", 0, 0)
def send_button():#Second button to send over socket
send_button =Button(window, text="Send",
font=font, bg="lime green",
command=lambda: send(),
height=height, width=width,
padx=padx, pady=pady)
send_button.grid(column=10, row = 8, rowspan=1)
send_button()
HOST = "127.0.0.1"
PORT = 33000
BUFSIZ = 1024
ADDR = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive)
receive_thread.start()
window.mainloop()
This is the server:
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
def accept_incoming_connections():
"""Sets up handling for incoming clients."""
while True:
client, client_address = SERVER.accept()
print("%s:%s has connected." % client_address)
# client.send(bytes("Greetings from the cave! Now type your name and press enter!", "utf8"))
addresses[client] = client_address
Thread(target=handle_client, args=(client,)).start()
def handle_client(client): # Takes client socket as argument.
"""Handles a single client connection."""
name = client.recv(BUFSIZ).decode("utf8")
# welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % name
# client.send(bytes(welcome, "utf8"))
msg = "%s has joined the chat!" % name
# broadcast(bytes(msg, "utf8"))
clients[client] = name
while True:
msg = client.recv(BUFSIZ)
if msg != bytes("{quit}", "utf8"):
broadcast(msg)
# broadcast(msg, name + ": ")
else:
client.send(bytes("{quit}", "utf8"))
client.close()
del clients[client]
broadcast(bytes("%s has left the chat." % name, "utf8"))
break
def broadcast(msg, prefix=""): # prefix is for name identification.
"""Broadcasts a message to all the clients."""
for sock in clients:
sock.send(bytes(prefix, "utf8") + msg)
clients = {}
addresses = {}
HOST = '127.0.0.1'
PORT = 33000
BUFSIZ = 1024
ADDR = (HOST, PORT)
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.bind(ADDR)
if __name__ == "__main__":
SERVER.listen(5)
print("Waiting for connection...")
ACCEPT_THREAD = Thread(target=accept_incoming_connections)
ACCEPT_THREAD.start()
ACCEPT_THREAD.join()
SERVER.close()
And this is client2:
from threading import Thread
import tkinter
import pickle
def receive():
"""Handles receiving of messages."""
while True:
try:
msg =client_socket.recv(BUFSIZ)#.decode("utf-8")
msg = pickle.loads(msg)
print(msg)
# msg_list.insert(tkinter.END,msg)
except OSError: # Possibly client has left the chat.
break
def send(event=None): # event is passed by binders.
"""Handles sending of messages."""
msg = my_msg.get()
my_msg.set("") # Clears input field.
client_socket.send(bytes(msg, "utf8"))
if msg == "{quit}":
client_socket.close()
top.quit()
def on_closing(event=None):
"""This function is to be called when the window is closed."""
my_msg.set("{quit}")
send()
top = tkinter.Tk()
top.title("Chatter")
messages_frame = tkinter.Frame(top)
my_msg = tkinter.StringVar() # For the messages to be sent.
scrollbar = tkinter.Scrollbar(messages_frame) # To navigate through past messages.
# Following will contain the messages.
msg_list = tkinter.Listbox(top,width=40,height=10)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
messages_frame.pack()
entry_field = tkinter.Entry(top, textvariable=my_msg)
entry_field.bind("<Return>", send)
entry_field.pack()
send_button = tkinter.Button(top, text="Send", command=send)
send_button.pack()
top.protocol("WM_DELETE_WINDOW", on_closing)
#----Now comes the sockets part----
# HOST = input('Enter host: ')
HOST = "127.0.0.1"
# PORT = input('Enter port: ')
PORT = 33000
if not PORT:
PORT = 33000
else:
PORT = int(PORT)
BUFSIZ = 1024
ADDR = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive)
receive_thread.start()
tkinter.mainloop()
As I said above, the msg variable in client2, the one that receives the message, is printed as a tuple but a for loop will iterate over each character of the strings contained.
Using the pickle module I received two separate errors.
When I pass .decode("utf-8) and then .loads() it says "Could not find MARK).
Without the .decode(), the error is "unpickling stack underflow".
My desired outcome is for each of the individual strings that arrive over the TCP socket to be added to the listbox in client2 on a new line, and without the ('', '') symbols.
Should I try to convert it to a .json object?
Or will another networking module produce better results?
I'm sorry about the length of code and the potentially obvious answer. Beginner to networking.

python why I keep getting ValueError from select.select: file descriptor cannot be a negative integer (-1)

I try to make a simple tkinter GUI chatting interface using socket and select, however keep getting ValueError file descriptor cannot be a negative integer (-1) when connects to server.
it shows:
r,w,e = select.select(socket_list,[],[],0)
ValueError: file descriptor cannot be a negative integer (-1)
below is the full script for client:
from tkinter import *
import socket,select,sys,time
HOST = ''
PORT = 0
class Connection():
def __init__(self):
self.t1 = Toplevel()
self.scrollbar = Scrollbar(self.t1)
self.textbox = Text(self.t1,yscrollcommand=self.scrollbar.set)
self.e3 = Entry(self.t1)
self.b2 = Button(self.t1,text='close window',command=self.close_window)
self.s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.s.settimeout(2)
self.scrollbar.pack(side=LEFT,fill=Y)
self.textbox.pack()
self.e3.pack(fill=X)
self.b2.pack(side=BOTTOM,fill=X)
self.connect_server()
self.in_and_out()
def connect_server(self):
global HOST, PORT
try:
self.s.connect((str(HOST),int(PORT)))
except Exception as e:
print('Error with [%s,%s] Exception type: %s'% (HOST,PORT,e))
self.close_window()
def in_and_out(self):
while True:
root.update_idletasks()
root.update()
socket_list = [sys.stdin,self.s]
r,w,e = select.select(socket_list,[],[],0)
for sock in r:
if sock==self.s:
data=self.s.recv(4096).decode()
if not data:
print('disconnected from server.')
self.close_window()
else:
print(data)
self.textbox.insert(END,'>: %s\n'% data)
else:
name = self.s.getsockname()
self.e3.bind("<Return>",self.enter_pressed)
def enter_pressed(self):
msg = self.e3.get()
self.textbox.insert(END,">: %s\n"% msg)
self.s.send(msg.encode())
self.e3.delete(0,'end')
def close_window(self):
self.s.close()
self.t1.destroy()
def try_linking():
global HOST, PORT
HOST = s1.get()
PORT = i1.get()
print(HOST,PORT)
conn = Connection()
root = Tk()
l1 = Label(root,text='Host:')
l2 = Label(root,text='Port:')
s1 = StringVar()
i1 = IntVar()
e1 = Entry(root,textvariable=s1)
e2 = Entry(root,textvariable=i1)
s1.set('192.168.4.101')
i1.set(9009)
b1 = Button(root,text='Connect',command=try_linking)
l1.pack()
e1.pack()
l2.pack()
e2.pack()
b1.pack(fill=X)
if __name__=='__main__':
root.mainloop()
this script is supposed to start by entering the host and port then press try_link button then a chatting window pops up upon connection.
please advise and thank you

How to send and receive messages on a server socket?

I am trying to create a simple "chat room" of the sort, where I do not know how many messages I will get from a client but my server will receive them all, display them and eventually respond. The problem is that when I click on the respond textbox, my code crashed. I am really unsure about where my problem lies and any help will work.
from Tkinter import *
import tkMessageBox
import socket
import threading
# Global variables
SendConfirmation = "0"
ConnectionConfirmation = "0"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
data_old = ""
# Initiates socket and connection
def ConnectBind():
global ConnectionConfirmation
global sock
server_address = (IP_Entry.get(), int(Port_Entry.get()))
sock.bind(server_address)
tkMessageBox.showinfo("Bind Successful", "Connected to " + IP_Entry.get() + " at port " + Port_Entry.get())
ConnectionConfirmation = "1"
# Sets the disconnect signal
def DisconnectBind():
global ConnectionConfirmation
ConnectionConfirmation = "2"
# Sets the Send Signal
def SendMessage():
global SendConfirmation
SendConfirmation="1"
# Running background listen
def BackgrounListen():
global data_old
data = connection.recv(1024)
if data != None:
if data != data_old:
Message_Text.insert('1.0', data + '\n')
# Window set up
root = Tk()
root.title('TCP/IP software')
ConnectionFrame = Frame(root)
ConnectionFrame.pack(side=TOP, fill=X)
SendFrame = Frame(root)
SendFrame.pack(side=TOP, fill=X)
MessageFrame = Frame(root)
MessageFrame.pack(side = BOTTOM)
# Connection information frame
IP_Label = Label(ConnectionFrame, text="IP address: ")
IP_Entry = Entry(ConnectionFrame, bd=10, text="Enter IP address here")
Port_Label = Label(ConnectionFrame, text="Port number: ")
Port_Entry = Entry(ConnectionFrame, bd=10, text="Enter port number here")
IP_Label.grid(row=0, column=0)
IP_Entry.grid(row=0, column=1)
Port_Label.grid(row=1, column=0)
Port_Entry.grid(row=1, column=1)
# Connect and bind to the address and port
Connect_Button = Button(ConnectionFrame, text="Connect", command=ConnectBind)
Connect_Button.grid(row=3, column=0)
DisConnect_Button = Button(ConnectionFrame, text="Disconnect", command=DisconnectBind)
DisConnect_Button.grid(row=3, column=1)
# Send messages frame
SendMessage_Entry = Entry(SendFrame, bd=10, text="Type your message here")
SendMessage_Button = Button(SendFrame, text="Send Message", command=SendMessage)
SendMessage_Entry.pack()
SendMessage_Button.pack()
# Information/Messages display frame
Message_Text = Text(MessageFrame, height=8, width=50)
Message_Scroll = Scrollbar(MessageFrame)
Message_Text.pack(side=LEFT, fill=Y)
Message_Scroll.pack(side=RIGHT, fill=Y)
Message_Scroll.config(command=Message_Text.yview())
Message_Text.config(yscrollcommand=Message_Scroll.set)
# Start the GUI before running
root.update_idletasks()
root.update()
#Working out main
Message_Text.insert(INSERT, "Software started")
while ConnectionConfirmation != "2":
if ConnectionConfirmation == "1":
sock.listen(1)
connection, client_address = sock.accept()
Message_Text.insert('1.0', "Client connected\n")
connection.sendall("connected to server")
root.update_idletasks()
root.update()
while ConnectionConfirmation == "1":
if connection.recv#:
# if SendConfirmation == "1":
# connection.send(SendMessage_Entry.get())
# SendConfirmation = "0"
background_thread = threading.Thread(target=BackgrounListen())
background_thread.daemon = True
background_thread.start()
root.update_idletasks()
root.update()
elif ConnectionConfirmation == "2":
sock.close()
#Message_Text.insert('1.0', "Socket properly closed")
#ConnectionConfirmation = "0"
#root.update_idletasks()
#root.update()
root.update_idletasks()
root.update()
the easiest way is to make the chat room like a reverse shell .
i write the code here .
hope to be helpful. ;-)
[CODE] : server.py
import socket
s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
ip = socket.gethostname()
port = 4444
s.bind((ip , port))
name = input("Enter Your Name : ")
try :
while True :
s.listen(5)
conn , addr = s.accept()
print("Connection From : ",addr)
while True :
data = conn.recv(1024)
print()
print(data)
print()
msg = input("Enter the Massage : ")
msg = name + " : " + msg
if msg == "exit" :
conn.close()
s.close()
break
else :
conn.send(bytes(msg , "UTF-8"))
except IOError as error :
print("\n [!] Connection Faild [!] \n",error)
conn.close()
s.close()
[CODE] : client.py
import socket
ip = socket.gethostname() #ip to connect
port = 4444
s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
name = input("Enter Your Name : ")
try :
s.connect((ip , port))
print("[+] Connected to : " , ip)
while True :
print()
cmd = input("Enter the Massage : ")
if cmd == "exit" :
s.close()
break
exit()
else :
cmd = name + " : " + cmd
s.send(bytes(cmd , "UTF-8"))
data = s.recv(1024000)
data = strings.byte2str(data)
print()
print(data)
except IOError as error :
print("\nDisconnected From : ",ip,"\n",error)
s.close()
have a good time :-)

running file opening dialog of server using tkFileDialog on client

I am trying to make a simple system to transfer a file from server to client.
I want to show the client a file open dialog using tkFileDialog.
The problem is when I run the client & server the dialog box gets opened in server rather than client. I thought about send the object of tkFileDialog via
con.send(str(tkFileDialog.askopenfilename(initialdir='~', title='Choose a text file/program')))
If someone could help me out with this it will be really helpful or if someone has a better idea to open server filesystem in client without ssh
The full code is
server.py:
import socket,os
import Tkinter,tkFileDialog,tkMessageBox
def startServer(portName,ip):
if portName != '' and ip != '':
tkMessageBox.showinfo('Server Started','Server running!!! ok will be enabled after transfer')
port = int(portName)
ipName = ip
sd = socket.socket()
sd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #reuse socket
sd.bind((ipName, port))
sd.listen(50)
con, addr = sd.accept()
print ' connection from ' + str(addr)
con.send(tkMessageBox.showinfo('connected', 'Connection Successful'))
while True:
con.send(str(tkFileDialog.askopenfilename(initialdir='~', title='Choose a text file/program')))
fileN = con.recv(1024)
if os.path.isfile(fileN):
con.send(tkMessageBox.showinfo('Process completed', 'Rerun server to transfer again'))
con.send('exists')
fileN = str(fileN)
#read contents
fd = open(fileN, 'r')
buff = fd.read()
print buff
print len(buff)
fd.close()
#send contents
con.send(str(len(buff)-1))
print con.recv(14) #acknowledgement of length received
con.send(buff)
break
else:
con.send(tkMessageBox.showerror('Failed', 'Select appropriate file'))
con.send('ne')
sd.close()
else:
tkMessageBox.showerror('Failed','Failed to start server. Give appropriate inputs')
def main():
root = Tkinter.Tk()
root.geometry('300x200')
root.title('Server')
ipLabel = Tkinter.Label(root,text='\nEnter IP Address of server\n')
portLabel = Tkinter.Label(root, text='\nEnter Port Address of server\n')
ipEntry = Tkinter.Entry(root)
portEntry = Tkinter.Entry(root)
connectButton = Tkinter.Button(root,
text='Run',
command=lambda: startServer(portEntry.get(), ipEntry.get())
)
ipLabel.pack()
ipEntry.pack()
portLabel.pack()
portEntry.pack()
connectButton.pack()
root.mainloop()
main()
the client.py:
import socket
import Tkinter,tkMessageBox
def establishConnection(ipEntry,portEntry,root):
if ipEntry != '' and portEntry != '':
port = int(portEntry)
ipName = str(ipEntry)
sd = socket.socket()
sd.connect((ipName, port))
# ack if connection established
sd.recv(1024)
while True:
#file select dialog
fileN = sd.recv(1024)
sd.send(fileN) #send file name to open
sd.recv(1024) #dialog after file selected or not
fileAck = sd.recv(6) #acknowledge if file correct
if fileAck == 'exists':
leng = int(sd.recv(10))
sd.send('length recieved')
buff = str(sd.recv(leng))
saveLabel = Tkinter.Label(root, text='\n\nSave with Name\n')
saveNameEntry = Tkinter.Entry(root)
saveButton = Tkinter.Button(root,
text='SAVE',
command=lambda: saveFile(saveNameEntry.get(), buff, root))
saveLabel.pack()
saveNameEntry.pack()
saveButton.pack()
break
sd.close()
def saveFile(fileN, buff, root):
fd = open(fileN, 'w')
fd.write(buff)
fd.close()
tkMessageBox.showinfo('Operation Complete','file saved as '+fileN)
root.destroy()
def main():
root = Tkinter.Tk()
root.geometry('300x600')
root.title('Client')
ipLabel = Tkinter.Label(root,text='\nEnter IP Address of server\n')
portLabel = Tkinter.Label(root, text='\nEnter Port Address of server\n')
ipEntry = Tkinter.Entry(root)
portEntry = Tkinter.Entry(root)
connectButton = Tkinter.Button(root,
text='Connect',
command=lambda: establishConnection(ipEntry.get(), portEntry.get(),root)
)
ipLabel.pack()
ipEntry.pack()
portLabel.pack()
portEntry.pack()
connectButton.pack()
root.mainloop()
main()
The file dialog works only for the system that opens it. You can't use it to pick files on a remote system.

writing text area in python, implementing sockets

I am doing a simulation of a print server in python, files are sent using sockets to a server which has to be placed in a printer queue. When the client initiates communication with the server must provide an ID (user) and PASSWORD, which will be checked against a list on the server can be verified in a file "passwordlist.txt" which has the following format:
akira Aaron
alazrea Ababa
alexander Abbott
andy Abe
andycapp Abel
anxieties Abelian
anxiety Abelson
bailey Aberdeen
batman robin
bd Abidjan
Both programs must have a graphical interface on the display:
* Client: user field, password, file to send to print and disconnect from the server.
* Server: A list of files that are queued for printing
On the server should be displayed a list of files that have been properly sent to the queue for printing.
For this I decided to use a "text area" but I have a problem, only shows me the first file in the command to print text area, when the client terminates the connection and if another client tries to connect to the server just crash the program does and does absolutely nothing. What am I doing wrong? I think the problem is that i'm putting part of the instruction code "root.mainloop ()", i have this doubt. how can resolve this failure? im stuck With This..thanks to all
Here's the Client Code:
#! /python26/python.exe
#! -*- coding: utf-8 -*-
from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog
import Tkinter
import sys
import socket
import tkMessageBox
flag = False
class Exit_Button(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.pack()
self.widget1()
def salir():
root.destroy()
def adjuntar_imprimir():
global flag
if (flag==False):
tkMessageBox.showinfo("Error", "You must login")
salir ()
else:
# get filename
filename = tkFileDialog.askopenfilename(**file_opt)
# open file on your own
if filename:
s.send (filename)
f= open(filename, 'rb')
l = f.read(1024)
while (l):
s.send(l)
l = f.read(512)
def iniciar_sesion():
global flag
#invoco el metodo connect del socket pasando como parametro la tupla IP , puerto
login = value.get()
password = value_2.get()
if ((len(login) == 0) or (len(password)) == 0):
tkMessageBox.showinfo("Error", "insert correct login and password")
salir ()
else:
s.send(login)
s.send(password)
recibido = s.recv(1024)
tkMessageBox.showinfo("Notify", recibido)
if (recibido=="Error Check user & Password"):
salir ()
else:
flag = True
####--------------------------------------------------------------------------------####
root = Tk()
s = socket.socket()
s.connect(("localhost", 9999))
# define options for opening or saving a file
file_opt = options = {}
options['defaultextension'] = '' # couldn't figure out how this works
options['filetypes'] = [('all files', '.*'), ('text files', '.txt')]
options['initialdir'] = 'C:\\'
options['initialfile'] = 'myfile.txt'
options['parent'] = root
options['title'] = 'This is a title'
frame = Frame(root)
frame.pack(side=LEFT)
frame.master.title("Servicio de impresion")
value = StringVar()
value_2 = StringVar()
w = Label(root, text="User Name", fg="red")
w.pack(side = LEFT)
entry_1 = Entry(root, textvariable=value_2, bd =5, show="*")
entry_1.pack(side = RIGHT)
z= Label(root, text="Password", fg="red")
z.pack(side = RIGHT)
entry_0 = Entry(root, textvariable=value, bd =5)
entry_0.pack(side = RIGHT)
##---------------login----------------
button_0= Button (frame, text = "login", command= iniciar_sesion, bg='black', foreground ="red")
button_0.pack()
##--------------Attach and print File------------
button_3 = Button (frame, text= "print", command=adjuntar_imprimir, bg='black',foreground ="red")
button_3.pack(side=LEFT)
##-----------------Exit------------------------
button_1 = Button(frame, text= "exit", command=salir, bg='black', foreground ="red")
button_1.pack()
root.mainloop()
The Server Code:
from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog
import Tkinter
import sys
import socket
import tkMessageBox
def onclick():
pass
root = Tk()
root.title("Print Server")
text = Text(root, width=60, height=30)
text.pack()
s = socket.socket()
s.bind(("localhost", 9999))
s.listen(100)
i=0
while (True):
sc, address = s.accept()
print "Connection from: ", address
recibido1 = sc.recv(1024)
recibido2 = sc.recv(1024)
print "login:", recibido1, "password:", recibido2
salida = (str(recibido1)+" "+str(recibido2)+"\n")
archivo = open("passwordlist.txt", "r")
while True:
linea = archivo.readline() #Leo del archivo
if (salida==linea):
log_ok ="login ok"
sc.send(log_ok)
break
if (len(linea))==0:
error= "Error Check user & Password"
sc.send(error)
break
f = open('print_'+ str(i)+".pdf",'wb') #abierto en escritura binaria
i=i+1
# recibimos y escribimos en el fichero
nombre_archivo = sc.recv(1024)
cadena = "On Impresion Queue.."+nombre_archivo+"\n"
text.insert(INSERT, cadena)
print "On impresion Queue.."+nombre_archivo
l = sc.recv(1024)
while (l):
f.write(l)
l = sc.recv(1024)
if not l:
notification= "Complete transfer"
sc.send(notification)
break
f.close()
sc.close()
root.mainloop()
s.close()
The program does not tell me any error just when another client tries to login, the client interface is doing nothing.
I don't know why it crashes, but I know why only one client can connect. Your server just isn't designed to handle multiple clients. When one client connects, all the server does is listen to that client - any other client trying to connect is simply ignored.
The solution is simple: Multithreading. Spawn a new thread for each connecting client, and let the "main" thread accept new connections.
The resulting "while(True)" loop should look somewhat like this:
from threading import Thread
tkinterThread= Thread(target=Tk.mainloop, args=[root])#spawn a new Thread object
tkinterThread.start()#make the thread execute the tkinter mainloop
#please note: I'm not sure if the two lines above actually work; I can't test them because Tkinter won't work for me.
def listenToClient(sc, address):
recibido1 = sc.recv(1024)
recibido2 = sc.recv(1024)
print "login:", recibido1, "password:", recibido2
salida = (str(recibido1)+" "+str(recibido2)+"\n")
archivo = open("passwordlist.txt", "r")
while True:
linea = archivo.readline() #Leo del archivo
if (salida==linea):
log_ok ="login ok"
sc.send(log_ok)
break
if (len(linea))==0:
error= "Error Check user & Password"
sc.send(error)
break
f = open('print_'+ str(i)+".pdf",'wb') #abierto en escritura binaria
i=i+1
# recibimos y escribimos en el fichero
nombre_archivo = sc.recv(1024)
cadena = "On Impresion Queue.."+nombre_archivo+"\n"
text.insert(INSERT, cadena)
print "On impresion Queue.."+nombre_archivo
l = sc.recv(1024)
while (l):
f.write(l)
l = sc.recv(1024)
if not l:
notification= "Complete transfer"
sc.send(notification)
break
f.close()
sc.close()
while (True):
sc, address = s.accept()
print "Connection from: ", address
clientThread= Thread(target=listenToClient, args=[sc,address])#spawn a new thread object
clientThread.start()#start the thread; it'll execute the "listenToClient" function, passing it "sc" and "address" as arguments
This code will (well, should) spawn a thread that takes care of the GUI, meanwhile it'll accept connection requests from clients and spawn a new thread for every client, which checks the client's username and password, and then keeps listening until the client disconnects.

Categories