My server is starting normal, but when I run my client on that port, it's not working. This is my error code from the client:
OSError: [WinError 10038] An operation was attempted on something that is not a socket
This is the script of the client:
chat_client.py
import sys
import socket
import select
def chat_client():
if(len(sys.argv) < 3) :
print ('Usage : python chat_client.py hostname port')
sys.exit()
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
# connect to remote host
try :
s.connect((host, port))
except :
print ('Unable to connect')
sys.exit()
print ('Connected to remote host. You can start sending messages')
sys.stdout.write('[Me] '); sys.stdout.flush()
while 1:
socket_list = [sys.stdin, s]
# Get the list sockets which are readable
ready_to_read,ready_to_write,in_error = select.select(socket_list ,
[], [])
for sock in ready_to_read:
if sock == s:
# incoming message from remote server, s
data = sock.recv(4096)
if not data :
print ('\nDisconnected from chat server')
sys.exit()
else :
#print data
sys.stdout.write(data)
sys.stdout.write('[Me] '); sys.stdout.flush()
else :
# user entered a message
msg = sys.stdin.readline()
s.send(msg)
sys.stdout.write('[Me] '); sys.stdout.flush()
if __name__ == "__main__":
sys.exit(chat_client())
Related
i am trying to set up communication with an ethernet device connected to my computer. Connection seems to work ok, when i connect the socket to the device's IP address and port, but when I try to send a command to the device, it returns the [error 10054 - connection was forcibly interrupted by the remote host]. The code I have so far is like this:
import socket
import time
import logging
logging.basicConfig(filename='conn.txt', filemode='w')
logging.warning('Starting...')
address = ('192.168.1.23', 23)
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ok = soc.connect_ex(address)
if ok == 0:
logging.warning('Connected to device ' + str(ok))
else:
logging.warning('Connection failed ' + str(ok))
### send at command
command = 'AT+SENSOR_IDS'
cmd_to_send = command + '\r\n'
cmd_to_send = cmd_to_send.encode('ascii')
logging.warning('Sending at command')
soc.sendall(cmd_to_send)
logging.warning('at command sent, waiting for echo')
# read echo
echo = soc.recv()
logging.warning('received echo: ' + echo)
print('finished')
When i try to "reconnect" with another soc.connect_ex(address), it tells me that the socket is in use.
Thank you for all your help.
EDIT:
So because I don't know much about the device thanks to the lack of documentation, I decided on simulating the problem just using an Echo server and a client example on a localhost. I have this code:
Server side:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 1001)
s.bind(server_address)
s.listen(1)
# looking for clients
while True:
print('waiting for connection')
connection, client_address = s.accept()
# when client connects
try:
print('Connection from %s port %s' % client_address )
# get all the data and echo it back
while True:
data = connection.recv(15)
print('Received: ' + str(data))
if not data:
try:
s.sendall(data)
except:
print('echoing data failed')
break
finally:
connection.close()
Client side:
import socket
address = ('127.0.0.1', 1001)
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ok = soc.connect_ex(address)
try:
if ok == 0:
print('Connected to device ' + str(ok))
else:
print('Connection failed ' + str(ok))
except Exception as e:
soc.close()
print("connection not succesful, error returned :", e)
try:
cmd_to_send = 'AT+SENSOR_IDS\r\n'.encode('ascii')
bytes_sent = soc.sendall(cmd_to_send)
if bytes_sent == None:
print('Command sent succesfully')
else:
print('AT command failed to be sent')
# read echo
echo = soc.recv()
print('received echo: ' + echo)
soc.close()
except:
try:
soc.close()
print('at command or echo reading failed')
except:
print('Process finished socket exception occured')
After the command is received by the server, it can't be echoed back to the client as the socket closes and is not working further. How to keep the socket alive?
Thank you for your help
You must close the sockets that you opened otherwise they will be open until a timeout reached.
Try this:
import socket
import time
import logging
logging.basicConfig(filename='conn.txt', filemode='w')
logging.warning('Starting...')
address = ('192.168.1.23', 23)
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
ok = soc.connect_ex(address)
if ok == 0:
logging.warning('Connected to device ' + str(ok))
else:
logging.warning('Connection failed ' + str(ok))
except Exception as e:
soc.close()
print("Connection is not successful, error returned :", e)
try:
### send at command
command = 'AT+SENSOR_IDS'
cmd_to_send = command + '\r\n'
cmd_to_send = cmd_to_send.encode('ascii')
logging.warning('Sending at command')
soc.sendall(cmd_to_send)
logging.warning('at command sent, waiting for echo')
# read echo
echo = soc.recv()
logging.warning('received echo: ' + echo)
except:
try:
soc.close()
print('Process Finished Succefully')
except:
print('Process Finished Socket Exception Occured')
I am trying to set up a server that can send each client - commands.
One command is 'lock' which locks the screen of the client.
When a client gets the word "lock" it runs this code on the client:
import ctypes
ctypes.windll.user32.LockWorkStation()
This code does lock the screen however- it ends my connection with the client..
How can I make the client stay connected but still locked?
Note: The locking is not forever! it is only once, like putting the client's computer in sleep mode until he wants to unlock the screen.
Hope I was clear enough. Thanks for helping!
Server:
import socket
def main():
sock = socket.socket()
sock.bind(('0.0.0.0', 4582))
print("Waiting for connections...")
sock.listen(1)
conn, addr = sock.accept()
print ("New connection from: ", addr)
while 1:
command = input("Enter command> ")
if command == 'shutdown':
sock.send(b'shutdown')
elif command == 'lock':
sock.send(b'lock')
else:
print ("Unknown command")
data = sock.recv(1024)
print (data)
if __name__ == '__main__':
main()
Client:
import socket
import ctypes
def main():
sock = socket.socket()
sock.connect(('127.0.0.1', 4582))
while 1:
data = sock.recv(1024)
print (data)
if data == 'lock':
sock.send(b'locking')
ctypes.windll.user32.LockWorkStation()
sock.recv(1024)
if __name__ == '__main__':
main()
I adapted the example from the Python docs to your needs.
Example for server.py:
import socket
HOST = '127.0.0.1'
PORT = 4582
with socket.socket() as s:
print('Waiting for connection...')
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = input('Which command? ')
if data in ['lock', 'shutdown']:
conn.send(data.encode())
else:
print('Command unknown')
Example for client.py:
import ctypes
import socket
HOST = '127.0.0.1'
PORT = 4582
with socket.socket() as s:
s.connect((HOST, PORT))
while True:
data = s.recv(1024).decode()
if not data:
print('Server disconnected')
break
print('Received command:', data)
if data == 'shutdown':
print('Shutting down client...')
break
if data == 'lock':
print('Locking...')
ctypes.windll.user32.LockWorkStation()
Before you say this is a duplicate, I have looked at many articles on this and still can't fix it.
I am making a very basic chat client and server python program.
However after connecting through my client, it says 'Connected' on the server console, but disconnects immediately on the chat one with the error 'OSError: [WinError 10038] An operation was attempted on something that is not a
socket'
CHAT
def chat_client():
if(len(sys.argv) not in (3, 4)):
print("Usage: python chat_client.py <hostname> <port> <optional-username>\n")
sys.exit()
host = sys.argv[1]
port = int(sys.argv[2])
username = ""
if len(sys.argv) == 4:
username = sys.argv[3]
else:
username = "Guest"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
# Connect to remote host
try:
s.connect((host, port))
except:
print("Unable to connect")
sys.exit()
print("Connected to remote host. You can start sending messages")
print("*** Press Control-C to log off ***\n")
sys.stdout.write("[" + username + "] ")
sys.stdout.flush()
while True:
socket_list = [sys.stdin, s]
try:
# Get the list sockets which are readable
ready_to_read, ready_to_write, in_error = select.select(socket_list, [], [])
except KeyboardInterrupt:
system("clear")
sys.stdout.write("\nYou have logged off\n")
sys.stdout.flush()
sys.exit()
SERVER
HOST = ""
SOCKET_LIST = []
RECV_BUFFER = 4096
PORT = 9009
CONVERSATION = ""
def chat_server():
global CONVERSATION
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
# Add server socket object to the list of readable connections
SOCKET_LIST.append(server_socket)
print("Chat server started on port " + str(PORT))
while True:
try:
# Get the list sockets which are ready to be read through select
# 4th arg, time_out = 0 : poll and never block
ready_to_read, ready_to_write, in_error = select.select(SOCKET_LIST, [], [], 0)
for sock in ready_to_read:
# A new connection request recieved
if sock == server_socket:
sockfd, addr = server_socket.accept()
SOCKET_LIST.append(sockfd)
print("Client (%s, %s) connected" % addr)
broadcast(server_socket, sockfd, "[%s, %s] entered our chatting room\n" % addr)
# A message from a client, not a new connection
else:
# Process data recieved from client
try:
# Recieving data from socket
data = sock.recv(RECV_BUFFER)
if data:
# there is something in the socket
# broadcast(server_socket, sock, "\r" + '[' + str(sock.getpeername()) + '] ' + data) # old
broadcast(server_socket, sock, "\r" + data)
else:
# Remove the socket that's broken
if sock in SOCKET_LIST:
SOCKET_LIST.remove(sock)
# at this stage, no data probably means the connection has been broken
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
except:
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
continue
except KeyboardInterrupt:
server_socket.close()
sys.exit()
server_socket.close()
# broadcast chat messages to all connected clients
def broadcast(server_socket, sock, message):
for socket in SOCKET_LIST:
# send the message only to peer
if socket != server_socket and socket != sock:
try:
socket.send(message)
except:
# Broken socket connection
socket.close()
# Broken socket, remove it
if socket in SOCKET_LIST:
SOCKET_LIST.remove(socket)
if __name__ == "__main__":
sys.exit(chat_server())
From select's documentation:
File objects on Windows are not acceptable, but sockets are. On
Windows, the underlying select() function is provided by the WinSock
library, and does not handle file descriptors that don’t originate
from WinSock.
This rules out using sys.stdin.
Alternatives:
Use Cygwin (No modifications to code needed)
Create a thread that waits on sys.stdin (like here)
Go the full Windows route and use WaitForMultipleObjects
Use some library that abstracts these details away, I like libuv but haven't used it with python
Another thing: Don't use select with a zero timeout in an infinite loop. This busy waiting is really inefficient. Instead omit the timeout to have select block till a descriptor becomes ready.
I'm trying to create a chatroom based on sockets which works on windows.
I have a server script:
# chat_server.py
import sys
import socket
import select
HOST = ''
SOCKET_LIST = []
RECV_BUFFER = 4096
PORT = 9009
def chat_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
threads = []
#add server socket object to the list of readable connections
SOCKET_LIST.append(server_socket)
print("Chat server started on port " + str(PORT))
while 1:
# get the list sockets wich are ready to be read through select
# 4th arg, tiome_out = 0 : poll and never block
ready_to_read,ready_to_write,in_error = select.select(SOCKET_LIST,[],[],0)
for sock in ready_to_read:
# a new connection request recieved
if sock == server_socket:
sockfd, addr = server_socket.accept()
SOCKET_LIST.append(sockfd)
print("Cient (%s, %s) connected" % addr)
broadcast(server_socket, sockfd, "[%s:%s] entered our chatting room\n" % addr)
# a message from a client, not a new connection
else:
# process data recieved from client,
try:
#receiving data from the socket.
data, addr = sock.recvfrom(RECV_BUFFER)
if data:
# there is something in the socket
broadcast(server_socket, sock, "\r" + '[' + str(sock.getpeername()) + ']' + data)
else:
# remove the socket that's broken
if sock in SOCKET_LIST:
SOCKET_LIST.remove(sock)
# at this stage, no data means probably the connection has been broken
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
# exception
except:
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
continue
server_socket.close()
# broadcast chat messages to all connected clients
def broadcast (server_socket, sock, message):
for socket in SOCKET_LIST:
# send the message only to peer
if socket != server_socket and socket != sock :
try :
socket.send(message)
except :
# broken socket connection
socket.close()
# broken socket, remove it
if socket in SOCKET_LIST:
SOCKET_LIST.remove(socket)
if __name__ == "___main__":
sys.exit(chat_server())
chat_server()
And a client script:
# chat_client.py
import sys
import socket
import select
from threading import Thread
def chat_client():
if(len(sys.argv) < 3):
print('Usage: python chat_client.py hostname port')
sys.exit()
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
#connect to remote host
try:
s.connect((host,port))
except:
print('Unable to connect')
sys.exit()
print('Connected to remote host. You can start sending messages')
sys.stdout.write('[Me] '); sys.stdout.flush()
sock_send = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_send.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock_send.bind((host, port))
def send_msg(sock):
while True:
# user entered a message
s.send(sys.stdin.buffer.readline())
sys.stdout.write('[Me] '); sys.stdout.flush()
def recv_msg(sock):
while True:
# incoming message from remote server, s
data, addr = sock.recvfrom(1024)
if not data :
print('\nDisconnected from chat server')
sys.exit()
else:
#print data
sys.stdout.write(data)
sys.stdout.write('[Me] '); sys.stdout.flush()
Thread(target=send_msg, args=(sock_send,)).start()
Thread(target=recv_msg, args=(sock_send,)).start()
if __name__ == "__main__":
sys.exit(chat_client())
The program is executed with:
$ python chat_server.py
$ python chat_client.py localhost 9009
If I run the code I won't get any Error. When I run several clients at the same time they all connect to the server correctly, but one client doesn't get the text another client has written.
I think something is wrong with the server's broadcast function, but I'm not sure what it is.
I already searched for similar questions, but I didn't find anything useful for fixing this problem. Please Help!
I am trying to create a simple chat application on python . I have created the client.py and server.py taking reference from this site
the server runs fine while running of client code gives error as
to resolve this issue I have reset the winsock and also tried to reinstall tcp/ip from this site
how do I resolve this issue
client.py
import socket, select, string, sys
def prompt() :
sys.stdout.write('<You> ')
sys.stdout.flush()
#main function
if __name__ == "__main__":
if(len(sys.argv) < 3) :
print 'Usage : python telnet.py hostname port'
sys.exit()
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
# connect to remote host
try :
s.connect((host, port))
except :
print 'Unable to connect'
sys.exit()
print 'Connected to remote host. Start sending messages'
prompt()
while 1:
socket_list = [sys.stdin, s]
# Get the list sockets which are readable
read_sockets, write_sockets, error_sockets = select.select(socket_list , [], [])
for sock in read_sockets:
#incoming message from remote server
if sock == s:
data = sock.recv(4096)
if not data :
print '\nDisconnected from chat server'
sys.exit()
else :
#print data
sys.stdout.write(data)
prompt()
#user entered a message
else :
msg = sys.stdin.readline()
s.send(msg)
prompt()