BlockingIOError when trying to connect socket - python

I am building a TCP Client in Python, that is supposed to try to connect to the server until a connection is established or the program is closed.
I define a timeout on a blocking socket, but after the first attempt to connect I receive
BlockingIOError: [Errno 114] Operation already in progress
Here is a little code example:
import socket
TCP_IP = '192.168.1.10'
TCP_PORT = 7
class TcpClient:
def __init__(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.settimeout(5)
def connect(self):
self.s.connect((TCP_IP, TCP_PORT))
if __name__ == "__main__":
client = TcpClient()
while True:
try:
client.connect()
except socket.timeout:
pass
If I understand the python documentation correctly, the timeout should occur when the connection attempt was not successful. That would mean that the socket is not trying to establish a connection anymore, but it seems like it still is.
I tried to close the socket, too, but then I would need to create a new socket for every new connection attempt. I cannot believe that this is the perfect solution.
I am open for any suggestions or help regarding this problem.
Thank you!

Related

conn.send('Hi'.encode()) BrokenPipeError: [Errno 32] Broken pipe (SOCKET)

hi i make model server client which works fine and i also create separate GUI which need to two input server IP and port it only check whether server is up or not. But when i run server and then run my GUI and enter server IP and port it display connected on GUI but on server side it throw this error. The Server Client working fine but integration of GUI with server throw below error on server side.
conn.send('Hi'.encode()) # send only takes string BrokenPipeError: [Errno 32] Broken pip
This is server Code:
from socket import *
# Importing all from thread
import threading
# Defining server address and port
host = 'localhost'
port = 52000
data = " "
# Creating socket object
sock = socket()
# Binding socket to a address. bind() takes tuple of host and port.
sock.bind((host, port))
# Listening at the address
sock.listen(5) # 5 denotes the number of clients can queue
def clientthread(conn):
# infinite loop so that function do not terminate and thread do not end.
while True:
# Sending message to connected client
conn.send('Hi'.encode('utf-8')) # send only takes string
data =conn.recv(1024)
print (data.decode())
while True:
# Accepting incoming connections
conn, addr = sock.accept()
# Creating new thread. Calling clientthread function for this function and passing conn as argument.
thread = threading.Thread(target=clientthread, args=(conn,))
thread.start()
conn.close()
sock.close()
This is part of Gui Code which cause problem:
def isOpen(self, ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, int(port)))
data=s.recv(1024)
if data== b'Hi':
print("connected")
return True
except:
print("not connected")
return False
def check_password(self):
self.isOpen('localhost', 52000)
Your problem is simple.
Your client connects to the server
The server is creating a new thread with an infinite loop
The server sends a simple message
The client receives the message
The client closes the connection by default (!!!), since you returned from its method (no more references)
The server tries to receive a message, then proceeds (Error lies here)
Since the connection has been closed by the client, the server cannot send nor receive the next message inside the loop, since it is infinite. That is the cause of the error! Also there is no error handling in case of closing the connection, nor a protocol for closing on each side.
If you need a function that checks whether the server is online or not, you should create a function, (but I'm sure a simple connect is enough), that works like a ping. Example:
Client function:
def isOpen(self, ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((str(ip), int(port)))
s.send("ping".encode('utf-8'))
return s.recv(1024).decode('utf-8') == "pong" # return whether the response match or not
except:
return False # cant connect
Server function:
def clientthread(conn):
while True:
msg = conn.recv(1024).decode('utf-8') #receiving a message
if msg == "ping":
conn.send("pong".encode('utf-8')) # sending the response
conn.close() # closing the connection on both sides
break # since we only need to check whether the server is online, we break
From your previous questions I can tell you have some problems understanding how TCP socket communication works. Please take a moment and read a few articles about how to communicate through sockets. If you don't need live communications (continous data stream, like a video, game server, etc), only login forms for example, please stick with well-known protocols, like HTTP. Creating your own reliable protocol might be a little complicated if you just got into socket programming.
You could use flask for an HTTP back-end.

Python Socket Auto Reconnect

I'm a beginner in Python. So I wanted to make if a server shuts down, disconnects, the client just keeps connecting until the server is opened again. I get this error:
File "C:\Users\Laurynas\Desktop\project\client.py", line 24, in reconnect server1.connect((HOST, PORT)) OSError: [WinError 10056] A connect request was made on an already connected socket
Current client.py code:
import socket
import time
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = socket.gethostbyname(socket.gethostname())
PORT = 8888
# Check at the first try
def connect():
try:
server.connect((HOST, PORT))
messages()
except ConnectionRefusedError:
print("reconnecting, please wait...")
time.sleep(0.1)
connect()
# Check at the second, third, etc.
def reconnect():
try:
server1.connect((HOST, PORT))
messages()
except ConnectionRefusedError:
print("reconnecting, please wait...")
time.sleep(0.1)
reconnect()
def messages():
while True:
try:
command = server.recv(1024).decode()
print(command)
except:
reconnect()
pass
connect()
With the exception of listening sockets that are used for many accepts, data sockets cannot be reconnected and reused. On the client side a new socket needs to be created for the new connection and on the server side a new accept needs to be made. The old sockets should also be closed to get them out of the kernel.
This poses a difficulty because a server won't automatically know which client is reconnecting and which higher level activity should be restarted. This has to be baked into the protocol you implement on top of the connection. In HTTP for instance, each GET/PUT/POST reidentifies itself so that the web server knows how to do that, perhaps using a cookie based session id.
Bottom line, you can't keep on calling server.connect to start it up again.

python ssl socket OSerror An operation was attempted on something that is not a socket

So before anyone says its a duplicate, I have seen multiple questions with that error, but could not notice any of that being the same as my problem.
I am trying to make a small project including a socket over SSL, and when trying to catch if a user is trying to connect with a raw socket and not ssl wrapped socket (which is raising a ConnectionResetError) I get a different error.
My code:
import socket
from classes import ClientThread
import ssl
from time import sleep
server = 'localhost'
port = 12345
threads = []
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile="cert.pem", keyfile="cert.pem")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((server, port))
print(f"[*] server started, listening on port {port}")
while True:
s.listen()
with context.wrap_socket(s, server_side=True) as ssock:
try:
conn, addr = ssock.accept()
client = ClientThread(conn=conn, ip=addr[0], port=addr[1])
client.start()
threads.append(client)
print(f'Threads running: {len(threads)}')
except ConnectionResetError:
print(f'Could not establish ssl handshake with a client.')
The error i get is:
Traceback (most recent call last):
File "C:/Users/x/x/server.py", line 17, in <module>
s.listen()
OSError: [WinError 10038] An operation was attempted on something that is not a socket
I tried setting some sleep time after the exception maybe it needed to reset the socket but didnt hlep, tried to play a bit with the placement of the While True, and while resetting the entire socket help, I dont want to reset all my clients thread just because of a client who didnt try to log in with a SSL socket.
I think it has something to do with the wrap_socket because it modified the socket instance passed to it , but couldnt find a way to unwrap.
Thank you in advance!
listen enables a socket to take incoming connection requests (also called a "passive socket") and establishes a backlog of how many of those requests can be pending in the network stack at any given time. accept accepts one of those connections. You call listen once and accept many times.
Pull the listen outside of the while so that is only called once to establish this as a listening socket.

How to make a TCP server handle multiple clients?

I'm trying to make a Python server where multiple clients can connect but I've run into a problem I tried everything that I found on the internet.
I'm running a laptop whit windows 7 and an I3 processor.
This is the file called tcp:
import socket
def make_server (ip,port):
try:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((ip, port))
server.listen(1)
return server
except Exception as ex:
print(ex)
return None
def accept(server):
conn, addr = server.accept()
return conn
def make_client():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
return client
def client_connect(client,ip,port):
client.connect((ip,port))
def sendall(conn,mess):
conn.send(str(mess).encode("utf-8"))
def rec(conn,rate):
mess = conn.recv(rate).decode("utf-8")
return mess
def close(client):
client.close()
This is the server:
from multiprocessing import Process
from random import randint
import tcp
import sys
def start(sip, sport):
print("Making sob server...")
print("id= {}".format(sport))
sserver = tcp.make_server(sip, sport)
print("Sub Server Started!")
sconn = tcp.accept(sserver)
tcp.sendall(sconn, "connected!!")
while True:
try:
tcp.sendall(sconn, randint(0, 100))
except Exception as ex:
print("")
print("From server {} error:".format(port))
print(ex)
print("")
break
ip = "192.168.0.102"
port = 8000
subport = 9000
server = tcp.make_server(ip, port)
if server is None:
sys.exit(0)
print("Started!")
while True:
print("Wating for new connection!")
con = tcp.accept(server)
print("Connected!")
subport = subport + 1
tcp.sendall(con, subport)
print("New Port Sent!")
print("New Port = {}".format(subport))
subs = Process(target=start, args=(ip, subport))
subs.start()
subs.join()
This is the client:
import tcp
import time
nport = 0
ip = "192.168.0.102"
port = 8000
client = tcp.make_client()
tcp.client_connect(client,ip,port)
nport = tcp.rec(client,1024)
print(nport)
tcp.close(client)
nport = int(nport)
time.sleep(1)
print(nport)
client = tcp.make_client()
tcp.client_connect(client,ip,nport)
while True:
mess = tcp.rec(client, 1024)
if(mess):
print(mess)
The error is:
[WinError 10048]Only one usage of each socket address (protocol/network address/port) is normally permitted Python
Feel free to change anything you want.
If you need any info in plus just ask.
You are creating a socket in the client with tcp.make_client. You are then using that socket to connect to the server via tcp.client_connect. Presumably you successfully receive the new port number back from the server. But then you are trying to re-use the same socket to connect to those ports.
This is the proximate cause of your error: A socket can only be used for a single TCP connection. If you want to create a new connection, you must first create a new socket.
That being said, if you are simply trying to create a server that will accept multiple connections, you're making it way too complicated. The server can receive any number of connections on its single listening port, as long as a different address/port combination is used by each client.
One way to structure this in a server is something like this:
# Create and bind listening socket
lsock = socket.socket()
lsock.bind(('', port))
lsock.listen(1)
while True:
csock, addr = lsock.accept()
print("Got connection from {}".format(addr))
# Start sub-process passing it the newly accepted socket as argument
subs = Process(target=start, args=(csock, ))
subs.start()
# Close our handle to the new socket (it will remain open in the
# sub-process which will use it to talk to the client)
csock.close()
# NOTE: do not call subs.join here unless you want the parent to *block*
# waiting for the sub-process to finish (and if so, what is the point in
# creating a sub-process?)
There are several others ways to do it as well: you can create multiple threads to handle multiple connections, or you can handle all connections in a single thread by using select or with asynchronous I/O.
The client is typically much simpler -- as it usually only cares about its own one connection -- and doesn't care which way the server is implemented:
sock = socket.socket()
sock.connect((ip, port))
while True:
sock.send(...)
sock.recv(...)
If the client does wish to connect to the same server again, it simply creates a second socket and call its connect method with the same server IP and port.
Usually, the client never needs to specify its own port, only the server's port. It simply calls connect and the client-side operating system chooses an unused port for it. So the first time, the client creates a socket and connects it (to the server's listening port), the client-side OS may choose port 50001. The next time it creates and connects a socket, it may get 50002 and so on. (The exact port numbers chosen depend on the operating system implementation and other factors, such as what other programs are running and creating connections.)
So, given client IP 192.168.0.101 and server IP 192.168.0.102, and assuming the server is listening on port 8000, this would result in these two connections:
(192.168.0.101/50001) ====> (192.168.0.102/8000)
(192.168.0.101/50002) ====> (192.168.0.102/8000)

No connection could be made because the target machine actively refused it (despite mongod running) and unable to insert data into MongoDB

I have been trying to insert data (a 'hello world' string) from PLC into MongoDB using Python API (which pulls the data from PLC and pushes it into MongoDB). I have been getting the error message:
"D:\Python27\lib\socket.py, line 222, in meth return getattr(self._sock,name)(*args) error:
[Errno 10061] No connection could be made because the target machine
actively refused it"
despite having mongod running in the Services background for the code I have written below. Also, the server IP address on which MongoDB is present is 10.52.124.186 and address of PLC (which I am using it on my PC) is 10.52.124.135. I am have tried almost everything to sort it out and yet I haven't got a clue as to how to get past it. Where am I going wrong?
#!/usr/bin/python
import socket
import socket
import pymongo
from pymongo import MongoClient
import datetime
# Connection to server (PLC) on port 27017
server = socket.socket()
host = '10.52.124.135'
port = 27017
server.connect((host, port))
print server.recv(1024)
server.close
#Connection to Client (Mongodb) on port 27017
IP = '10.52.124.186'
PORT = 27017
BUFFER_SIZE = 1024
client = MongoClient('10.52.124.186', 27017)
db = client.RXMMongoDB
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((IP, PORT))
s.listen(1)
#connections loop
while True:
conn, addr = s.accept()
print 'Connection address:',addr
try:
# read loop
while True:
data = server.recv(BUFFER_SIZE)
if not data:
break
# send to Mongo
mongodoc = { "data": data, "date" : datetime.datetime.utcnow() }
db.AAAA.insert(mongodoc)
finally:
conn.close()
I don't know much about Python, but it seems odd to me that your closing the socket "server.close" and then trying to use it afterwards "data = server.recv(BUFFER_SIZE)".
Anyway, maybe you should start by printing the text from your PLC on the screen instead of trying to do it all in one go. It's usually easier if you break it down into smaller sections and then glue them back together when you know they are working separately.
Also see this post for tracing your error

Categories