It seems i have 2 errors, 1st is that cannot concatenate str and bytes, 2nd is that that the connection was closed by the remote host. Wanna help.
I want that this sends a message to all the clients that this person has left the chat, instead of that it is giving the 2nd answer.
Server_chat.py
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).decode('utf8')
if msg != bytes("{quit}", "utf8"):
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=""):
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()
client_chat.py
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
import tkinter
def receive():
"""Handles receiving of messages."""
while True:
try:
msg = client_socket.recv(BUFSIZ).decode("utf8")
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.
my_msg.set("Type your messages here.")
scrollbar = tkinter.Scrollbar(messages_frame) # To navigate through past messages.
# Following will contain the messages.
msg_list = tkinter.Listbox(messages_frame, height=15, width=50, yscrollcommand=scrollbar.set)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
msg_list.pack()
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 = '127.0.0.1'
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()
Error
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:43:08) [MSC v.1926 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>>
== RESTART: C:\Users\arun.kumar2\Documents\python\chatting app\server_chat.py ==
Waiting for connection...
127.0.0.1:59150 has connected.
127.0.0.1:59176 has connected.
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Users\arun.kumar2\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\arun.kumar2\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\arun.kumar2\Documents\python\chatting app\server_chat.py", line 28, in handle_client
broadcast(msg, name+": ")
File "C:\Users\arun.kumar2\Documents\python\chatting app\server_chat.py", line 40, in broadcast
sock.send(bytes(prefix, "utf8")+msg)
TypeError: can't concat str to bytes
Exception in thread Thread-3:
Traceback (most recent call last):
File "C:\Users\arun.kumar2\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\arun.kumar2\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\arun.kumar2\Documents\python\chatting app\server_chat.py", line 26, in handle_client
msg = client.recv(BUFSIZ).decode('utf8')
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
Error is at server_chat.py at line 40
You can't contact string with bytes type so you have to keep them both same type or chnage type of one of them.
def broadcast(msg, prefix=""):
for sock in clients:
sock.send(bytes(prefix+msg, "utf8"))
As the first error said, you cannot concat str (msg) and bytes, so use:
sock.send(bytes(prefix+msg, "utf8"))
Also you should not call bytes(...) on the argument of broadcast() like below:
broadcast(bytes(msg, "utf8"))
Since you have called bytes(...) inside broadcast(). Use below instead:
broadcast(msg)
For the second error, it is because the connection to client is lost but the server is still trying to read from client. You should use try/except to catch the connection lost.
Below is the modified handle_client() and broadcast():
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(msg) ###
clients[client] = name
while True:
try:
msg = client.recv(BUFSIZ).decode('utf8')
if msg != "{quit}": ###
broadcast(msg, name+": ")
else:
client.send(bytes("{quit}", "utf8"))
break
except (ConnectionResetError, ConnectionAbortedError):
break
client.close()
del clients[client]
broadcast("%s has left the chat." % name) ###
print(name, "disconnected")
def broadcast(msg, prefix=""):
for sock in clients:
sock.send(bytes(prefix+msg, "utf8"))
Related
I'm creating a simple chat server and when I try to connect a client I get this error:
Traceback (most recent call last):
File "C:\Users\OneDrive\Desktop\Py Files\chat_server.py", line 47, in <module>
recive()
File "C:\Users\OneDrive\Desktop\Py Files\chat_server.py", line 39, in recive
client.append(client)
AttributeError: 'socket' object has no attribute 'append'
Here is my code:
import threading
import socket
host = '127.0.0.1'
port = 20200
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen()
clients = []
nicknames = []
def brodcast(message):
for client in clients:
client.send(message)
def handle(client):
while True:
try:
message = client.recv(1024)
brodcast(message)
except:
index = clients.index(client)
clients.remove(client)
client.close()
nickname = nicknames[index]
brodcast(f'{nickname} left the chat'.encode('ascii'))
nicknames.remove(nickname)
break
def recive():
while True:
client, address = server.accept()
print(f"Connected with {str(address)}")
client.send('NICK'.encode('ascii'))
nickname = client.recv(1024).decode('ascii')
nicknames.append(nickname)
client.append(client)
print(f'{nickname} joined the chat!')
brodcast(f'{nickname} joined the chat!')
client.send('Connected to the chat')
thread = threading.Thread(target=handle, args=(client,))
thread.start()
recive()
I've provided the code for the server because that is where the error is. On the client end, there appears to be no issues.
I am making a python chatroom application for school with a functioning clientside and serverside script. I am now adding multiple functionalities to the chatroom to make it easier to use, one of which is hopefully spam protection. Is there a way I can record how many messages per a certain measurement of time the client is sending and if they go over the maximum they are muted for a certain amount of time?
clientside.py:
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
import tkinter as tkinter
#import tkinter.ttk as ttk
#from ttkthemes import ThemedStyle
from tkinter import END
from datetime import *
import time as tme
def receive():
while True:
try:
msg = client_socket.recv(BUFSIZ).decode("utf8")
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
msg_list.insert(tkinter.END, '[' + current_time + '] ' + msg)
msg_list.yview(END)
msg_list.yview()
except OSError:
break
def send(event=None):
msg = my_msg.get()
if msg.isspace() != True:
my_msg.set("")
client_socket.send(bytes(msg, "utf8"))
msg_list.yview(END)
msg_list.yview()
elif msg.isspace() == True:
my_msg.set("")
if msg == "{quit}":
client_socket.close()
top.quit()
def on_closing(event=None):
top.destroy()
my_msg.set("{quit}")
send()
top.quit()
top = tkinter.Tk()
top.resizable(width=False, height=False)
#top.iconbitmap('C:/Users/Ethen Dixon/Downloads/filled_chat_aH2_icon.ico')
top.title("Chat Room 90")
#style = ThemedStyle(top)
#style.set_theme("equilux")
messages_frame = tkinter.Frame(top)
my_msg = tkinter.StringVar()
my_msg.set("[type here]")
scrollbar = tkinter.Scrollbar(messages_frame)
msg_list = tkinter.Listbox(messages_frame, height=30, width=100, yscrollcommand=scrollbar.set)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
msg_list.pack()
messages_frame.pack()
entry_field = tkinter.Entry(top, textvariable=my_msg, width=100)
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)
HOST = input('Enter host: ')
PORT = input('Enter port: ')
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()
serverside.py:
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("Welcome to Chat Room 90! Please type in your username and press enter.", "utf8"))
addresses[client] = client_address
Thread(target=handle_client, args=(client,)).start()
def handle_client(client):
"""Handles a single client connection."""
name = client.recv(BUFSIZ).decode("utf8")
welcome = 'Welcome %s!' % 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, 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=""):
"""Broadcasts a message to all the clients."""
for sock in clients:
sock.send(bytes(prefix, "utf8")+msg)
clients = {}
addresses = {}
HOST = ''
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()
A way to do this is using the widget.unbind(sequence, funcid = None) method.
This, as the name suggests, deletes the bindings on w for a determined event.
Then you can use the tkinter built-in method root.after() to call a function that you create to rebind the button to the function.
But for this to work you need to bind the send_button using the .bind() method.
def rebind():
send_button.bind("<Button-1>", send)
send_button.bind("<Button-1>", send)
send_button.unbind("<Button-1>", funcid=None)
top.after(time in miliseconds, rebind)
I have a socket project running. This is the base project and some features.
This is server file:
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, 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 = "192.168.43.67"
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()
I added HOST ip manually getting from ifconfig.
and client file is:
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
import tkinter
def receive():
"""Handles receiving of messages."""
while True:
try:
msg = client_socket.recv(BUFSIZ).decode("utf8")
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.
my_msg.set("Type your messages here.")
scrollbar = tkinter.Scrollbar(messages_frame) # To navigate through past messages.
# Following will contain the messages.
msg_list = tkinter.Listbox(messages_frame, height=15, width=50, yscrollcommand=scrollbar.set)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
msg_list.pack()
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: ')
PORT = input('Enter port: ')
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()
When i run server and send to my friend my ip I get from ifconfig he can't connect yo my server.
I am sending wrong ip?
- Firewall desactivated
I am trying to make a simple chat application using Python 3. I have seen this work in the past, where my client is able to connect to my server, and messages can be sent successfully. I want to move the app from a script working in the python idle shell to a GUI built with TKinter. Using entry and button widgets, a client can connect to the server for a fraction of a second, then is immediately disconnected. This only seems to happen because I am trying to use tkinter.
Error message is:
%$%$ has connected.
Exception in thread Thread-33:
Traceback (most recent call last):
File "C:\Users\lmaor\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "C:\Users\lmaor\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\lmaor\Desktop\Server 2.py", line 32, in handle_client
name = client.recv(BUFSIZ).decode("utf8")
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
The client-side code is:
#Importing packages
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
import tkinter
from tkinter import *
from tkinter import messagebox
global client_socket
global HOST
global PORT
#These are here to stop the program breaking later on
HOST = 1
PORT = 1
BUFSIZ = 1024
client_socket = socket(AF_INET, SOCK_STREAM)
#This unsuccessfully connects to the server
def connect():
HOST = etyHost.get()
PORT = etyPort.get()
if not PORT:
PORT = 33000 # Default value.
else:
PORT = int(PORT)
client_socket = socket(AF_INET, SOCK_STREAM)
BUFSIZ = 1024
ADDR = (HOST, PORT)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive)
receive_thread.start()
#Creates a function to receive messages at any time
def receive():
while True:
try:
global client_socket
msg = client_socket.recv(BUFSIZ).decode("utf8")
msgChatlog.insert(END, msg)
except OSError:
break
#Creates a function to send messages
def send(event=None): #Event is passed by binders
msg = varMessage.get()
varMessage.set("") #Clears input field
client_socket.send(bytes(msg, "utf8"))
if msg == "{quit}":
client_socket.close()
top.quit()
#When closing window
def on_closing(event=None):
varMessage.set("{quit}")
send()
#Create tkinter window
jahchat = Tk()
jahchat.geometry("500x500")
jahchat.configure(background = "black")
jahchat.resizable(False, False)
jahchat.title("JahChat")
#
#Frame contains everything. useless
frmMessage = Frame()
#Var message is what goes into the chat
varMessage = StringVar() # For the messages to be sent.
varMessage.set("Type your messages here.")
#Scrollbar for the chatlog
srlChatlog = Scrollbar(frmMessage) # To navigate through past messages.
#
msgChatlog = Listbox(frmMessage, height=15, width=100, yscrollcommand=srlChatlog.set)
srlChatlog.pack(side=RIGHT, fill=Y)
msgChatlog.pack(side=LEFT, fill=BOTH)
msgChatlog.pack()
frmMessage.pack()
#
etyMessage= Entry(textvariable=varMessage)
etyMessage.bind("<Return>", send)
etyMessage.pack()
btnMessage = Button(text="Send", command=send)
btnMessage.pack()
#jahchat.protocol("WM_DELETE_WINDOW", on_closing)
#Entry box
etyHost = Entry(jahchat)
etyHost.pack()
etyHost.place(x = 0, y = 250)
#Entry box
etyPort = Entry(jahchat)
etyPort.pack()
etyPort.place(x = 0, y = 275)
#Button
btnConnect = Button(jahchat, text = "Connect", command = connect)
btnConnect.config(width = 20)
btnConnect.place(x = 0, y = 320)
#========================================================
#This is the code that sucessfully connects to the server
#HOST = input("host")
#PORT = input("port")
#if not PORT:
# PORT = 33000 # Default value.
#else:
# PORT = int(PORT)
#client_socket = socket(AF_INET, SOCK_STREAM)
#BUFSIZ = 1024
#ADDR = (HOST, PORT)
#print (ADDR)
#print (type(ADDR))
#client_socket.connect(ADDR)
#receive_thread = Thread(target=receive)
#receive_thread.start()
#===========================================================
jahchat.mainloop() # Starts GUI execution.
The server code is:
#Importing packages
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
#Sets up constant variables for later use
clients = {}
addresses = {}
HOST = '' #Client has to set this as their host to connect
PORT = 33000 #Client has to set this as their port to connect
BUFSIZ = 1024
ADDR = (HOST, PORT)
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.bind(ADDR)
#Creates a function that handles clients into the server
def accept_incoming_connections():
while True:
client, client_address = SERVER.accept()
print ("%$%$ has connected." .format(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()
#Takes client socket as argument.
def handle_client(client):
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, name+": ")
else:
client.send(bytes("{quit}", "utf8"))
client.close()
del clients[client]
broadcast(bytes("%s has left the chat." % name, "utf8"))
break
#Broadcasts message to whole server
def broadcast(msg, prefix=""): #Prefix is for name identification.
for sock in clients:
sock.send(bytes(prefix, "utf8")+msg)
def checkIP():
print (HOST, PORT, ADDR)
if __name__ == "__main__":
SERVER.listen(5) # Listens for 5 connections at max.
print("Waiting for connection...")
ACCEPT_THREAD = Thread(target=accept_incoming_connections)
ACCEPT_THREAD.start() #Starts the infinite loop.
ACCEPT_THREAD.join()
SERVER.close()
All answers appreciated.
I am ttrying to implement a multithread TCP server using Python. When I run the following code I obtain the following error:
Error
Incoming message: how are you
Unhandled exception in thread started by <function client_thread at 0x00000000024499 E8>
Traceback (most recent call last):
File "tcp_test2.py", line 32, in client_thread
message = recv_msg(conn)
File "tcp_test2.py", line 24, in recv_msg
raw_msglen = recvall(sock, 4)
File "tcp_test2.py", line 13, in recvall
raise EOFError('was expecting %d bytes but only received %d bytes before socket closed' % (length, len(data)))
EOFError: was expecting 4 bytes but only received 0 bytes before socket closed
Not sure where I am going wrong with implementing the threading function. Any help would be greatly appreciated.
Code
import argparse
import socket
import struct
from thread import start_new_thread
def recvall(sock, length):
data = b''
while len(data) < length:
packet = sock.recv(length - len(data))
if not packet:
raise EOFError('was expecting %d bytes but only received %d bytes before socket closed' % (length, len(data)))
data += packet
return data
def send_msg(sock, msg):
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock):
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
return recvall(sock, msglen)
def client_thread(conn):
while True:
message = recv_msg(conn)
print('Incoming message: {}'.format(message))
conn.sendall(b'Message Received') #send data to the socket
conn.close() #mark the socket closed
print('\tReply sent, socket closed')
Server
def server(interface, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((interface, port)) # the socket to address
sock.listen(1) #listen for connections made to the socket.
while True:
conn, sockname = sock.accept()
start_new_thread(client_thread,(conn,))
sock.close()
Client
def client(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
print('Client has been assigned socket name', sock.getsockname())
message = raw_input("Type your message: ")
send_msg(sock, message)
reply = recvall(sock, 16)
print('Server Response: {}'.format(reply))
print('\nSocket closed')
sock.close()
if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive over TCP')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('host', help='interface the sever listens at:' 'host the client sends to')
parser.add_argument('-p', metavar='PORT', type=int, default=1060, help='TCP port(default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.host, args.p)
This is my previous code which did not have any unhandled exceptions
import argparse
import socket
import struct
def recvall(sock, length):
data = b''
while len(data) < length:
packet = sock.recv(length - len(data))
if not packet:
raise EOFError('was expecting %d bytes but only received %d bytes before socket closed' % (length, len(data)))
data += packet
return data
def send_msg(sock, msg):
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recv_msg(sock):
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
return recvall(sock, msglen)
def server(interface, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((interface, port)) # the socket to address
sock.listen(1) #listen for connections made to the socket.
print('Listening at {}'.format(sock.getsockname())) #returns the socket's own address
while True:
conn, sockname = sock.accept()
print('Connection accepted from {}'.format(sockname))
print('\tServer Socket: {}'.format(conn.getsockname()))
print('\tClient Socket: {}'.format(conn.getpeername())) # return remote address to which socket is connected
message = recv_msg(conn)
print('Incoming message: {}'.format(message))
conn.sendall(b'Message Received') #send data to the socket
conn.close() #mark the socket closed
print('\tReply sent, socket closed')
def client(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
print('Client has been assigned socket name', sock.getsockname())
message = raw_input("Type your message: ")
send_msg(sock, message)
reply = recvall(sock, 16)
print('Server Response: {}'.format(reply))
print('\nSocket closed')
sock.close()
if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive over TCP')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('host', help='interface the sever listens at:' 'host the client sends to')
parser.add_argument('-p', metavar='PORT', type=int, default=1060, help='TCP port(default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.host, args.p)
Nothing is wrong. Your client closes the socket. The server detects this when it tries to read the next message. This should have been exactly what you expected.