I'm programming a basic chat program. The goal of this is first to set up the server by launching the server.py script then leave that running in the background. Then a user launches the client.py script and chooses a name then starts to type a message and send it. The problem is when I attempt to send it it returns this error.
Traceback (most recent call last):
File "C:\Users\Hello\AppData\Local\Programs\Python\Python35-32\client.py", line 38, in <module>
s.sendto(alias + ': ' + message.encode() , server)
TypeError: Can't convert 'bytes' object to str implicitly
Here's the server.py script ---
import socket
import time
host = '127.0.0.1'
port = 47015
clients = []
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
s.setblocking(0)
qutting = False
print("Server Started")
while not qutting:
try:
data, addr = s.recvfrom(1024)
if 'Quit' in str(data):
qutting = 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()
then the client.py script----
import socket
import threading
import time
tLock = threading.Lock()
shutdown = False
def recieving(name, sock):
while not shutdown:
try:
tLock.acquire()
while True:
data, addr = sock.recvfrom(1024)
data.decode()
print(str(data))
except:
pass
finally:
tLock.release()
host = '127.0.0.1'
port = 0
server = ("127.0.0.1", 47015)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
s.setblocking(0)
rT = threading.Thread(target=recieving, args=('RecvThread', s))
rT.start()
alias = input("Name: ")
message = input(alias + "->")
while message != 'q':
if message != '':
s.sendto(alias + ': ' + message.encode() , server)
tLock.acquire()
message = input(alias + '->')
tLock.release()
time.sleep(0.2)
shutdown = True
rT.join()
s.close()
So if you have any idea how to fix this it would be greatly appreciated also a side question is would there be a way to make it so that the receiving thread runs all the time so it actively updates the chat?
The problem is in this line:
s.sendto(alias + ': ' + message.encode() , server)
You are converting message to a bytes, but then you are adding unconverted strings to the bytes object. This is an invalid operation, as the error message is telling you, because the bytes can not be unambiguously converted to a string. Try to encode the whole thing:
s.sendto((alias + ': ' + message).encode() , server)
Related
I'm trying to make a python socket client/server chat app, but can't seem to work around this error. I've used netstat -a|findstr 7000 to make sure the port was available, and it was. I don't have any antivirus running besides Windows Security. I also tried it after turning off all firewalls on my computer--have not messed with firewall settings in my router. I'm running both files in Anaconda Powershell Prompt as admin.
Any help is appreciated.
Code for server.py :
from socket import AF_INET, socket, SOCK_STREAM
import threading
BUFSIZ = 1024
FORMAT = 'utf-8'
SERVER = '192.168.1.10'
ADDR = (SERVER, 7000)
server = socket(AF_INET, SOCK_STREAM)
server.bind(ADDR)
sockets = {server}
clients = {}
def accept_incoming_connections():
while True:
client, client_addr = server.accept()
print ("%s:%s has connected." % client_addr)
client.send(bytes("Enter your name and press enter."), FORMAT)
sockets[client] = client_addr
# client_thread = threading.Thread(target=handle_client, args=(client,)).start()
def handle_client(client):
client_name = client.recv(BUFSIZ).decode(FORMAT)
client.send(bytes("Type .exit when you're ready to quit.", FORMAT))
msg = "%s has entered the chat." % client_name
broadcast(bytes(msg, FORMAT))
clients[client] = client_name
while True:
msg = client.recv(BUFSIZ)
if msg == bytes(".exit", FORMAT):
client.send(bytes(".exit", FORMAT))
client.close()
del clients[client]
broadcast(bytes("%s has left the chat." % client_name, FORMAT))
break
else:
broadcast(msg, client_name)
def broadcast(msg, name=""):
for client in clients:
client.send(bytes(name, FORMAT) + msg)
if __name__ == "__main__":
server.listen()
print("Awaiting connection.")
accept_incoming_connections()
Code for client.py :
import socket
import threading
BUFSIZ = 1024
FORMAT = 'utf-8'
SERVER = '192.168.1.10'
ADDR = (SERVER, 7000)
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_sock.connect(ADDR)
def receive():
msg = client_sock.recv(BUFSIZ).decode(FORMAT)
print(msg)
def send():
msg = input('Enter msg: ')
msg.encode(FORMAT)
client_sock.send(msg)
if msg == ".exit":
client_sock.close()
receive_thread = Thread(target=receive)
receive_thread.start()
EDIT: I fixed it. I set SERVER to 'localhost' and PORT to 9999 for both server and client.
I've problem with python socket at s.sendto(data,addr)
and my code like this
import socket
def Main():
host = '127.0.0.1'
port = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
print("server started")
while True:
data, addr = s.recvfrom(1024)
print ("message from : "+ str(addr))
print ("from connected user : "+ str(data))
data = str(data.upper())
print ("sending : "+ str(data))
socket.sendto(data, addr)
and result
socket.sendto(data, addr)
AttributeError: module 'socket' has no attribute 'sendto'
s.close()
if __name__ == '__main__':
Main()
and at UdpClient s.sendto is working
It seems that you mistyped the socket.sendto(... statement: The AttributeError is raised since the method sendto() is to be called from instances of the class socket.socket (as you have in s), and not from the socketmodule itself. See here for more details about the meaning of that statement.
So you basically need to change socket.sendto(... to s.sendto(...
also, if you want to check the attributes of any x object,(apart from reading the docs) you can simply check its x.__dict__ field, as explained here
cheers
What are the intentions of this program:
I want to send some commands from a client to a server using sockets, the server then send these command to an Arduino using serial. And another thing that I want the server to do in the future is that periodically sends other commands to the Arduino without getting any input from the client, so the sockets needs to be non-blocking or there needs to be another way to run the code separately from the sockets code.
The problem is that the part that is supposed to send the command to the Arduino only runs once.
What I have come up with after playing with the debugger in Pycharm, is that the problem is that the following line blocks after a connection has been established, and thus not allowing the rest of the code to be run.
conn, addr = s.accept()
Is this correct, or is there something else wrong?
I have tried to set the socket to non-blocking but when I do this I get an error.
"BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately"
I have some basic knowledge of C/C++ and C# and am new to Python.
server.py
import socket
import serial
import sys
from _thread import *
import threading
import queue
# command that the client sends are "ON" and "OFF"
class serialConnect:
comPort =' '
baudrate = 115200
myserial = serial.Serial('COM5', baudrate)
def serialstart(self):
# self.comPort = input('Comport: ')
try:
self.myserial.open()
except IOError:
print('Port is already open!')
def serialRead(self):
data = self.myserial.read(16)
data.decode('UTF-8')
return data
def serialWrite(self, data):
data += '\n' #the arduino needs a \n after each command.
databytes = data.encode('UTF-8')
self.myserial.write(databytes)
print('send data: ', databytes)
def threaded_client(conn, dataqueue):
data = {bytes}
conn.send(str.encode('welcome, type your info \n'))
while True:
data = conn.recv(2048)
if not data:
break
reply = 'server output: ' + data.decode('UTF-8')
dataqueue.put(data.decode('UTF-8'))
print("Items in queue: ",dataqueue.qsize())
#conn.sendall(str.encode(reply))
print("Recieved data in threaded_client: ", data.decode('UTF-8') + '\n')
conn.close()
def Main():
ser = serialConnect()
host = ''
port = 5555
dataRecieved = 'hello'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
s.setblocking(1) #when set to non-blocking error occurs : "BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately"
workQueue = queue.Queue(10)
try:
s.bind((host,port))
except socket.error as e:
print(str(e))
s.listen(5)
print('waiting for a connection')
while True:
try:
conn, addr = s.accept() #once connection is established it blocks?
print('connected to: ' + addr[0] + ':' + str())
t = threading.Thread(target=threaded_client, args=(conn, workQueue))
t.daemon = True
t.start()
except:
e = sys.exc_info()
print('Error:', e)
# This section of code is only run once, doesn't matter if put inside try block or not. :(
dataRecieved = workQueue.get()
print('The recieved data: ', dataRecieved)
ser.serialstart()
ser.serialWrite(dataRecieved)
if __name__ == '__main__':
Main()
client.py
import socket
def Main():
host = '127.0.0.1'
port = 5555
message = "<,R,G,B,>"
mySocket = socket.socket()
mySocket.connect((host, port))
while message != 'q':
message = input(" -> ")
mySocket.send(message.encode())
mySocket.close()
if __name__ == '__main__':
Main()
Arduino Code
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
int LEDpin = 10;
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 13 as an output.
pinMode(10, OUTPUT);
Serial.begin(19200);
}
// the loop function runs over and over again forever
void loop() {
serialEvent();
if(stringComplete){
Serial.println(inputString);
if(inputString == "ON\n"){
digitalWrite(LEDpin, HIGH); // turn the LED on (HIGH is the voltage level)
}
if(inputString == "OFF\n"){
digitalWrite(LEDpin, LOW); // turn the LED off by making the voltage LOW
}
inputString = "";
stringComplete = false;
}
}
void serialEvent()
{
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
Refactored server code for anyone that is interested in it.
I am not sure if this is up to standard, but it is working.
import serial
import socket
import queue
import sys
import threading
class serialConnect:
comPort = 'COM5'
baudrate = 115200
myserial = serial.Serial(comPort, baudrate)
def serial_run(self):
# self.comPort = input('Comport: ')
try:
if not self.myserial.isOpen():
self.myserial.open()
else:
print('Port is already open!')
except IOError as e:
print('Error: ', e)
def serial_read(self):
data = self.myserial.read(16)
data.decode('UTF-8')
return data
def serial_write(self, data):
data += '\n' #the arduino needs a \n after each command.
databytes = data.encode('UTF-8')
self.myserial.write(databytes)
print('send data: ', databytes)
class socketServer:
host = ''
port = 5555
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.setblocking(1)
data_queue = queue.Queue(1)
def __init__(self):
try:
self.soc.bind((self.host, self.port))
except:
print('Bind error: ', sys.exc_info())
self.soc.listen(5)
def socket_accept_thread(self):
while True:
try:
print('Waiting for a new connection')
conn, addr = self.soc.accept()
client_thread = threading.Thread(target=self.threaded_client, args=(conn, self.data_queue))
client_thread.daemon = True
client_thread.start()
except:
print('Accept thread Error: ', sys.exc_info())
def threaded_client(self, conn, data_queue):
# conn.send(str.encode('welcome, type your info \n'))
try:
while True:
data = conn.recv(2048)
if not data:
break
# reply = 'server output: ' + data.decode('UTF-8')
data_queue.put(data.decode('UTF-8'))
print("Items in queue: ", data_queue.qsize())
# conn.sendall(str.encode(reply))
print("Received data in threaded_client: ", data.decode('UTF-8'))
except:
print("Error: ", sys.exc_info())
conn.close()
def get_data(self):
data = self.data_queue.get()
return data
def Main():
server = socketServer()
arduino_conn = serialConnect()
accept_thread = threading.Thread(target=server.socket_accept_thread)
data_received = 'Nothing received'
while True:
if not accept_thread.is_alive():
accept_thread.daemon = True
accept_thread.start()
arduino_conn.serial_run()
data_received = server.get_data()
arduino_conn.serial_write(data_received)
if __name__ == '__main__':
Main()
i've written the following script on PyCharm IDE:
import socket
import time
sock = socket(socket.AF_INET, socket.SOCK_DGRAM)
hexpacket "00 FF"
ip = raw_input('Target IP: ')
port = input('Port: ')
duration = ('Number of seconds to send packets: ')
timeout = time.time() + duration
sent = 0
while True:
if time.time() > timeout:
break
else:
pass
sock.sendto(hexpacket,(ip,port))
sent = sent +1
print "Send %s packet to %s through ports %s"(send, ip, port)
I get an output from the console of:
TypeError: 'module' object is not callable
I have tried to change the "import socket" statement to either "from socket import socket" and "from socket import *" but both did not help.
I also tried to use "pip install socket" but I get "could not find any downloads that satisfy the requirement socket".
Any idea how do I solve this simple issue? I thought socket is a basic module that comes with every python download.
Thanks for the answers..!
sock = socket(socket.AF_INET, socket.SOCK_DGRAM)
you are using socket object directly it's wrong it's throwing an error
TypeError: 'module' object is not callable
Try this::
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
So I am working on an iPhone app that requires a socket to handle multiple clients for online gaming. I have tried Twisted, and with much effort, I have failed to get a bunch of info to be sent at once, which is why I am now going to attempt socket.
My question is, using the code below, how would you be able to have multiple clients connected? I've tried lists, but I just can't figure out the format for that. How can this be accomplished where multiple clients are connected at once and I am able to send a message to a specific client?
Thank you!
#!/usr/bin/python # This is server.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 50000 # Reserve a port for your service.
print 'Server started!'
print 'Waiting for clients...'
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
while True:
msg = c.recv(1024)
print addr, ' >> ', msg
msg = raw_input('SERVER >> ')
c.send(msg);
#c.close() # Close the connection
Based on your question:
My question is, using the code below, how would you be able to have multiple clients connected? I've tried lists, but I just can't figure out the format for that. How can this be accomplished where multiple clients are connected at once and I am able to send a message to a specific client?
Using the code you gave, you can do this:
#!/usr/bin/python # This is server.py file
import socket # Import socket module
import thread
def on_new_client(clientsocket,addr):
while True:
msg = clientsocket.recv(1024)
#do some checks and if msg == someWeirdSignal: break:
print addr, ' >> ', msg
msg = raw_input('SERVER >> ')
#Maybe some code to compute the last digit of PI, play game or anything else can go here and when you are done.
clientsocket.send(msg)
clientsocket.close()
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 50000 # Reserve a port for your service.
print 'Server started!'
print 'Waiting for clients...'
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
print 'Got connection from', addr
while True:
c, addr = s.accept() # Establish connection with client.
thread.start_new_thread(on_new_client,(c,addr))
#Note it's (addr,) not (addr) because second parameter is a tuple
#Edit: (c,addr)
#that's how you pass arguments to functions when creating new threads using thread module.
s.close()
As Eli Bendersky mentioned, you can use processes instead of threads, you can also check python threading module or other async sockets framework. Note: checks are left for you to implement how you want and this is just a basic framework.
accept can continuously provide new client connections. However, note that it, and other socket calls are usually blocking. Therefore you have a few options at this point:
Open new threads to handle clients, while the main thread goes back to accepting new clients
As above but with processes, instead of threads
Use asynchronous socket frameworks like Twisted, or a plethora of others
Here is the example from the SocketServer documentation which would make an excellent starting point
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
"""
The RequestHandler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print "{} wrote:".format(self.client_address[0])
print self.data
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
Try it from a terminal like this
$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello
HELLOConnection closed by foreign host.
$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Sausage
SAUSAGEConnection closed by foreign host.
You'll probably need to use A Forking or Threading Mixin too
This program will open 26 sockets where you would be able to connect a lot of TCP clients to it.
#!usr/bin/python
from thread import *
import socket
import sys
def clientthread(conn):
buffer=""
while True:
data = conn.recv(8192)
buffer+=data
print buffer
#conn.sendall(reply)
conn.close()
def main():
try:
host = '192.168.1.3'
port = 6666
tot_socket = 26
list_sock = []
for i in range(tot_socket):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host, port+i))
s.listen(10)
list_sock.append(s)
print "[*] Server listening on %s %d" %(host, (port+i))
while 1:
for j in range(len(list_sock)):
conn, addr = list_sock[j].accept()
print '[*] Connected with ' + addr[0] + ':' + str(addr[1])
start_new_thread(clientthread ,(conn,))
s.close()
except KeyboardInterrupt as msg:
sys.exit(0)
if __name__ == "__main__":
main()
def get_clients():
first_run = True
startMainMenu = False
while True:
if first_run:
global done
done = False
Thread(target=animate, args=("Waiting For Connection",)).start()
Client, address = objSocket.accept()
global menuIsOn
if menuIsOn:
menuIsOn = False # will stop main menu
startMainMenu = True
done = True
# Get Current Directory in Client Machine
current_client_directory = Client.recv(1024).decode("utf-8", errors="ignore")
# beep on connection
beep()
print(f"{bcolors.OKBLUE}\n***** Incoming Connection *****{bcolors.OKGREEN}")
print('* Connected to: ' + address[0] + ':' + str(address[1]))
try:
get_client_info(Client, first_run)
except Exception as e:
print("Error data received is not a json!")
print(e)
now = datetime.now()
current_time = now.strftime("%D %H:%M:%S")
print("* Current Time =", current_time)
print("* Current Folder in Client: " + current_client_directory + bcolors.WARNING)
connections.append(Client)
addresses.append(address)
if first_run:
Thread(target=threaded_main_menu, daemon=True).start()
first_run = False
else:
print(f"{bcolors.OKBLUE}* Hit Enter To Continue.{bcolors.WARNING}\n#>", end="")
if startMainMenu == True:
Thread(target=threaded_main_menu, daemon=True).start()
startMainMenu = False
#!/usr/bin/python
import sys
import os
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 50000
try:
s.bind((socket.gethostname() , port))
except socket.error as msg:
print(str(msg))
s.listen(10)
conn, addr = s.accept()
print 'Got connection from'+addr[0]+':'+str(addr[1]))
while 1:
msg = s.recv(1024)
print +addr[0]+, ' >> ', msg
msg = raw_input('SERVER >>'),host
s.send(msg)
s.close()