I was reading about the Python websocket-client library and realized that, to receive data, we have to start a connection:
from websocket import create_connection
ws = create_connection("ws://echo.websocket.org/")
print "Received " + ws.recv() + "..."
What if I just need a one-way connection? Say a Python script is running on my laptop, and it periodically sends messages to a local web server.
To receive messages, the web server would have to start a connection, but starting a connection requires a URL to connect to. My Python script is not a web server, so it lacks a URL. How could the web server receive messages from the script?
I tried to let the server listen for clients to connect with it via
ws = websocket.WebSocket()
while 1:
print 'received "' + ws.recv()
However, I get an error.
in _recv
bytes = self.io_sock.recv(bufsize)
error: [Errno 107] Transport endpoint is not connected
That error output leads me to believe that the server needs to connect in order to receive.
If you would want one way connection to the server, you could just listen on plain socket or use UDP or use HTTP requests ore any other TCP protocol.
Related
I have read several different SO posts on using python as a TCP client and am not able to connect to a server sending data via TCP at 1hz which is hosted locally. The connection parameters I am using are:
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip=socket.gethostbyname("127.0.0.1")
port=1234
address=(ip,port)
client.connect(address)
while True:
print("test1")
data = client.recv(1024)
print("test2")
print(data)
I believe that it is failing on the second line of the while statement but do not know why because it hangs and I am not given an error. Below are links to the SO articles, I have read and I have attached a screenshot from a TCP client tool that I am able to connect to the data server with. I'm expecting the data to stream in my print statement, is this not how it works? Whats the best way to make a persistent connection to a TCP connection with python?
Researched:
(Very) basic Python client socket example,Python continuous TCP connection,Python stream data over TCP
Working with sockets: In order to communicate over a socket, you have to open a connection to an existing socket (a "client"), or create an open socket that waits for a connection (a "server"). In your code, you haven't done either, so recv() is waiting for data that will never arrive.
The simple case is connecting as a client to a server which is waiting/listening for connections. In your case, assuming that there is a server on your machine listening on port 1234, you simply need to add a connect() call.
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip=socket.gethostbyname("127.0.0.1")
port=1234
address=(ip,port)
client.connect(address) ## <--Add this line.
while True:
print("test1")
data = client.recv(1024)
print("test2")
print(data)
For a class assignment I need to use the socket API to build a file transfer application. For this project there two connections with the client and server, one is called the control and is used to send error messages and the other is used to send data. My question is, on the client side how can I keep the control socket open and waiting for any possible error messages to be received from the server while not blocking the rest of the program from running?
Example code (removed some elements)
#Create the socket to bind to the server
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,portNum))
clientSocket.send(sendCommand) # Send to the server in the control connection contains either the list or get command
(If command is valid server makes a data connection and waits for client to connect)
clientData = socket(AF_INET,SOCK_STREAM)
clientData.connect((serverName,dataport)) #Client connects
recCommand = clientData.recv(2000) #Receive the data from server if command is successful
badCommand = clientSocket.recv(2000) #But if there is an error then I need to skip the clientData.recv and catch the error message in bad Command
when there is an error, the data-socket should be closed by the server, so recv ends automatically.
I have a small server side program which accepts the connections from the clients and writes into the socket. I want to detect from the server side as soon as the client gets disconnected. I see the client has sent a TCP Fin when it disconnected and the server is detecting it only when it has some data to send towards the client and I see Broken pipe exception. Instead I want the server to be able to detect that the client has sent a Finish and immediately close the session. Can someone please help me by giving some inputs.
>>> Error sending data: [Errno 32] Broken pipe
[DEBUG] (Keepalive-Thread) Exiting
Server program to accept connections:
def enable_pce(ip):
#Step 1: Create a TCP/IP socket to listen on. This listens for IPv4 AFI
srv = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#Step 2: Prevent from "address in use" upon server restart
srv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#Step 3: Bind the socket to you server ip address
srv_address = (ip,55555)
print 'starting server on %s port %s' % srv_address
srv.bind(srv_address)
#Step 4: Listen for connections
srv.listen(1)
#Step 5: Wait for incoming connections
connection, peer_address = peer.accept()
print 'connection from', connection.getpeername()
return connection
the server is detecting it only when it has some data to send towards the client and I see Broken pipe exception.
Close of connection by the peer can be detected either by getting an error when writing to the socket (broken pipe) or by reading from the socket and getting nothing (no error, no data) back.
In most scenarios it only matters to detect disconnection if one wants to communicate with the peer (that is read or write). If you want to do this without actually reading or writing data you might check readability of the socket with select.select and if the socket is readable peek into the read buffer with recv and MSG_PEEK.
I am trying to use socketserver to create a simple server to send images to a client with TCP.
First I send a catalogue to the client and then it responds with a request.
In the handle of my server, I have this loop :
class MainHandler(socketserver.BaseRequestHandler):
def handle(self):
while 1:
try:
# Sending the catalogue
# Using my methods to get my catalogue with a HTTP header
response = self.server.genHTTPRequest(self.server.init.catalogue)
self.request.sendall(response.encode())
# Response of the client
self.data = self.request.recv(1024).decode()
if self.data:
print("Data received : {}".format(self.data))
except:
print("transmission error")
break;
In the main I use this line to create my server (it's in an other file) :
mainServer = MainServer.MainServer((init.adresse, int(init.port)), MainServer.MainHandler)
When I launch this program, the client connect successfully and receive the catalogue but it sends back only some data and the program jump in the exception of the try/catch. Without the try/catch, I got this error :
self.data = self.request.recv(1024).decode()
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
I don't understand what is the problem, maybe a synchronization missing or may I need to use threads ?
Thank you for your help
(I am using python 3.3)
The problem would be because of sendall(response.encode()) and this self.request.recv(1024).decode() has been done in the same socket and it could lead to ConnectionAbortedError.
You need to read all the data from the socket before putting other data into the socket. Like flushing of data.
Can both a client and a server be run in the same program at the same time in Python. I want to connect a client to an external server and a server to receive messages from that external server at the same time. Whenever my server receives message from that external server my client should send messages to that external server accordingly.
Following is the way I tried to achieve that ( Just the connecting part)
import select
import socket
host = 'localhost'
portClient = 6000
portServer = 7000
backlog = 5
size = 1024
client = socket.socket()
server = socket.socket()
client.connect((host,portClient))
client.send('#JOIN')
server.bind((host,portServer))
server.listen(backlog)
running = 1
while running:
c,address = server.accept()
c.close()
client.close()
server.close()
When I run this code, no response from the external server comes.
When the while loop is omitted. I get an error saying that our server has actively refused to accept the external server.
Can I achieve this by using Python select module or Threading module? Or is there a better way?
TCP socket is a bi-directional stream of bytes. You can, and should, do all your communication with the server over the same single socket.