I'm trying to connect a client to a serverr. After I connect I want to check do some sort of validation. (checking if I got the massage 'ready') and if not, try to connect again until the server will send 'ready' and not something else.
tcp_sock = socket.socket()
tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcp_sock.bind(('', 7865))
connected = False
while not connected:
tcp_sock.connect(('192.168.0.111', 7865))
if tcp_sock.recv(1024) == b'ready':
connected = True
else:
tcp_sock.close()
if I put tcp_sock.close() after the else, I get this error when connecting again: an operation was attempted on something that is not a socket.
if I put pass instead of tcp_sock.close() (do not close the socket) I get this error when connecting again: Only one usage of each socket address (protocol/network address/port) is normally permitted.
PS. It works without errors without the tcp_sock.bind(('', 7865)) but I have to bind the client to a specific port (here 7865) and I'm using tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) to be able to reconnect again with the server.
How can I reconnect to the server without getting an error?
I think you are doing it correctly but I would suggest you use normal receiveing methods as it'll be easier for python to send and receive data.
CLIENT.py
import socket
import sys
import select
my_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
my_socket.connect(("__YOUR_IP__",7865)) #IMPORTANT
sys.stdout.write('your message: ')
sys.stdout.flush()
while True:
#...
else:
data = my_socket.recv(1024)
print "data" , data
If a TCP connection is not successful connect will throw an error. So handling exceptions from connect method should be enough to check if you are connected.
But if you want to fix this way; your close method also releases the socket therefore you need to define tcp-connect again in the while loop.
Related
I'm Trying to send and receive data using TCP communication.
I tried to communicate using the IP of a specific embedded device, but i check that the 'connect' was going well even when the device was turned off.
When the device is turned off, I want to output an error message, but I can't check it because the connect is performed normally.
So, I checked with wireshark and I found something strange.
My code
import socket
HOST = '105.0.0.121' # random IP
PORT = 9999
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.settimeout(2)
client_socket.connect((HOST, PORT))
client_socket.send('some data'.encode())
data = client_socket.recv(1024)
print('Received', repr(data.decode()))
client_socket.close()
I use random IP 105.0.0.121
I expect at client_socket.connect((HOST, PORT)) raise an error, but at line 'data = client_socket.recv(1024)' raise the error that print "socket.timeout: timed out".
wireshark image
When I checked with Wireshark, it seems to have sent an "ACK" from 105.0.121.
Because of receiving ACK, it seems that the "connect" has passed normally, but I don't know why this phenomenon occurs.
Give me a help plz
Thank you
I have the following code, run with Python 2.7 (on Mac OS) (needed because it's going into a legacy application). If LISTEN_BACKLOG is less than the number of clients, then after a few iterations I will get a "Connection reset by peer" on one of the clients during the recv() call, and sometimes during the connect().
For example, if you run 1 instance of the server and 2 instances of the client, with LISTEN_BACKLOG = 1, then you will get the issue very quickly.
server.py
import socket
LISTEN_BACKLOG = 1
exit_condition = False
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind(('127.0.0.1', 12345))
listener.settimeout(0.2)
listener.listen(LISTEN_BACKLOG)
while not exit_condition:
try:
server = listener.accept()[0]
server.send(' ')
server.close()
except socket.timeout:
# Timed-out connection so go around and wait again
pass
client.py
while True:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 12345))
print "Connected"
data = client.recv(1) # <-- Get "Connection reset by peer" here sometimes
if data == ' ':
print "Got Data"
else:
print "ERROR: Received data is wrong: ", data, "\n"
break
client.close()
print "Closed"
I am using a small socket timeout for the socket accept on the server, because I need to periodically check an exit condition for the while loop in the larger application. I know this is not ideal, but regardless I would expect it to work.
Can you please help me understand why the "Connection reset by peer" occurs?
EDIT:
I have also tried an updated version of my code with Python3 and the behaviour is the same: "Connection reset by peer" at the recv() line.
If anyone else is coming across the same issue, I believe it is only a problem on MacOS. Perhaps the python socket implementation has a bug in MacOS. I've tried on Linux and I cannot reproduce the issue there.
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.
I am writing a client-sever program based on Python socket.
The client sends a command to the server and the server responds.
But now, some client can broadcast a message to other clients, so the client can receive more than one response at the same time.
data = s.recv(1024)
the line of code above will retrieve only one response from the server.
but if I use a while loop like this
while True:
data = s.recv(1024)
if not data: break
actually, data=s.recv(1024) will block the program when there is no data left.
I don't want to block the program and want to retrieve all the responses available in the connection at one time. Can anyone find a solution? Thank you.
You can use the select module to wait until the socket is readable or until a timeout has elapsed; you can then perform other processing. For example:
while True:
# If data can be received without blocking (timeout=0), read it now
ready = select.select([s], [], [], 0)
if s in ready[0]:
data = s.recv(1024)
# Process data
else:
# No data is available, perform other tasks
You could make the socket (s) non-blocking. This way, it will retrieve all the received responses and when there is none, it will return back. Of course, with non-blocking, you will have to periodically retry.
You could make the socket (s) non-blocking using the setblocking() method:
s.setblocking(0)
The other option is to use another thread to handle the receive part. This way, your main thread can continue doing its main task and act upon the message only if it receives one.
You can use socket.setblocking or socket.settimeout:
import socket
import sys
HOST = 'www.google.com'
PORT = 80
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.setblocking(0)
s.sendall('Hello, world')
try:
data = s.recv(1024)
except:
print 'Oh noes! %s' % sys.exc_info()[0]
s.close()
socket.recv takes two parameters, the second is a set of flags. If you're on a Linux system, you can do man recv for a list of flags you can supply, and their corresponding errors.
Lastly, in general, you can't really know that the other side is done with sending you data (unless you're controlling both sides), even if you're both following a protocol. I believe the right way to go about it is to use timeouts, and quit after sending a reset (how you do this will depend upon what protocol you're using).
I'm building a game-server in Python. The functionality is pretty well-defined. The server will listen on the port 6000 and a remote client will send a request. Then the server will establish a connection to the client's port 7000. From then on, the client will keep sending 'requests' (basically, strings such as "UP#", "DOWN#", "SHOOT#" etc.) to server's port 6000.
This is the problem. I have made a 'server' who listens on the port 6000. This means I cannot bind a client to the same port. Is there a way that I can get the data string of an incoming request in a server? So far, I only have this.
What am I doing wrong here? Any workarounds for this issue? In short, can I read the incoming request string from a client in the server code?
Thanks in advance.
def receive_data(self):
errorOccured = False
connection = None
try:
listener = socket.socket() # Create a socket object.
host = socket.gethostname()
port = 6000 # The port that the server keeps listening to.
listener.bind(('', port))
# Start listening
listener.listen(5)
statement = ("I:P0:7,6;8,1;0,4;3,8;3,2;1,6:5,4;9,3;8,7;2,6;1,4;2,7;6,1;6,3:2,1;8,3;5,8;9,8;7,2;0,3;9,4;4,8;7,1;6,8#\n","S:P0;0,0;0#","G:P0;0,0;0;0;100;0;0:4,3,0;5,4,0;3,8,0;2,7,0;6,1,0;5,8,0;1,4,0;1,6,0#", "C:0,5:51224:824#","G:P0;0,0;0;0;100;0;0:4,3,0;5,4,0;3,8,0;2,7,0;6,1,0;5,8,0;1,4,0;1,6,0#","G:P0;0,1;2;0;100;0;0:4,3,0;5,4,0;3,8,0;2,7,0;6,1,0;5,8,0;1,4,0;1,6,0#")
# This is just game specific test data
while True:
c, sockadd = listener.accept() # Establish connection with client.
print 'incoming connection, established with ', sockadd
i = 0 # Just a counter.
while i<len(statement):
try:
self.write_data(statement[i], sockadd[0])
time.sleep(1) # The game sends updates every second to the clients
i = i + 1
#print listener.recv(1024) -- this line doesn't work. gives an error
except:
print "Error binding client"
c.close() # Close the connection
return
except:
print "Error Occurred"
I'm going to answer it because I got some help and figured it out.
The most basic thing I can do is to use the client connection which is c for this purpose. In here, instead of the commented line data=listener.recv(1024) I should have used data= c.recv(1024). Now it works.
Another way is to use SocketServers with a StreamingRequestHandler. While this is ideal for usage of typical servers, if a lot of objects are involved it could reduce the flexibility.