I'm trying to setup a basic socket program using TCP connections in Python, such as creating a socket, binding it to a specific address and port, as well as sending and receiving a HTTP packet.
I'm having trouble receiving the request message from the client.
I'm using the following:
message = serverSocket.receive
But when I go to the socket, port and file that's in my server directory through my browser I get the following error from IDLE:
AttributeError: 'socket' object has no attribute 'receive'
Is this the wrong approach to receive a request message from a client?
In order to receive data from a client/server via TCP in python using sockets:
someData = sock.recv(1024)
That is because no method is defined in the socket class for receive as your error states. You should use:
socket.recv(bufsize)
Related
I have quite a complex TCP/IP server that connects to several clients. I was running into an issue where my clients were not being updated that the socket was closing. I believe I need to call both socket.shutdown() and socket.close() to be able send a server closing advisory to all of the clients. However, I get an OS error whenever I call socket.shutdown().
OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
Does anybody know why this is happening? Or some other way of closing the socket while still sending the advisory to all connected clients? I could always write a custom command that resets all of the clients before calling socket.close(), but something seems wrong with my server. Below is minimum reproducible example.
import socket
import selectors
class server_test:
host = ''
port = 12345
sel = selectors.DefaultSelector()
def __init__(self):
self.start_server()
self.stop_server()
#Server Functions
def start_server(self):
self.lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.lsock.bind((self.host, self.port))
self.lsock.listen()
print("Server starting, listening on ",. (self.host, self.port))
self.lsock.setblocking(False)
self.sel.register(self.lsock, selectors.EVENT_READ, data=None)
def stop_server(self):
print("Shutting server down")
self.lsock.shutdown(1)
self.lsock.close()
I believe I need to call both socket.shutdown() and socket.close() to be able send a server closing advisory to all of the clients.
No. A shutdown(1) on a connected socket will send a FIN to the peer to signal that the local system will not send more data, but it might actually accept more data. A shutdown(0) will stop receiving data locally and reject any data send by the peer. A close() essentially combines a shutdown(1) and a shutdown(0).
self.lsock.listen()
...
self.lsock.shutdown(1)
You are trying to tell the peer of self.lsock that you will no longer send data. But self.lsock is the local listener socket which is not itself connected and thus has no peer. Since you are thus try to do an operation which requires a connected socket on a socket which is not connected (only listening) it will result in the error "... socket is not connected ...".
If you want to shutdown the connection to all clients you actually have to call shutdown or close on all connected sockets (i.e. result from self.lsock.accept() and not on the listener socket.
i built a simple DNS server.. and i'm just trying to print the data (the whole packet) but my server stuck at the recvfrom part.
i tried to open a file that i got as adminstor which changes my DNS server to 127.0.0.1 but it doesn't work.
this is my code:
i tried to write some url's on my browser but my server doesn't get nothing and stuck at the recv.
import socket
myserver = sokcet.socket(socket.AF_INET, socket.SOCKET_DGRAM)
myserver.bind(('0.0.0.0',53))
data, addr = myserver.recvfrom(1024)
print data
I am writing TLS server in Python. I accept a connection from a client, wrap the socket and then try to read data - without success.
My server inherits from socketserver.TCPServer. My socket is non-blocking - I overwrote server_bind() method. Socket is wrapped, but handshake has to be done separately, because of the exception which is raised otherwise:
def get_request(self):
cli_sock, cli_addr = self.socket.accept()
ssl_sock = ssl.wrap_socket(cli_sock,
server_side=True,
certfile='/path/to/server.crt',
keyfile='/path/to/server.key',
ssl_version=ssl.PROTOCOL_TLSv1,
do_handshake_on_connect=False)
try:
ssl_sock.do_handshake()
except ssl.SSLError as e:
if e.args[1].find("SSLV3_ALERT_CERTIFICATE_UNKNOWN") == -1:
raise
return ssl_sock, cli_addr
To handle received data, I created a class which inherits from socketserver.StreamRequestHandler (I tried also with BaseRequestHandler, but with no luck, ended with the same problem - no data received).
When I print self.connection in handle() method, I can see that it is of type SSLSocket, fd is set (to some positive value), both local and remote IP and port have values as expected, so I assume that a client is successfully connected to my server and the connection is opened. However when I try to read data
self.connection.read(1)
There should be more bytes received, I tried with 1, 10, 1024, but it does not make any difference, the read() method always returns nothing. I tried to check len or print it, but there is nothing to be printed.
I was monitoring packages using Wireshark. And I can see that the data I am expecting to read, comes to my server (I checked that IP and port are the same for self.connection and in Wireshark), which sends ACK and then receives FIN+ACK from the client. So it looks like the data comes and are handled properly on a low level, but somehow read() method is not able to access it.
If I remove wrap_socket() call, then I am able to read data, but that is some data which client is sending for authentication.
I am using Python 3.4 on Mac machine.
How is that possible that I can in Wireshark that packets are coming, but I am not able to read the data in my code?
I'm using a class RequestHandler(SocketServer.BaseRequestHandler)to handle incoming connections to a server.
I am trying to get the name of the client which is stored as an attribute that sends data to this server, but right now I can only get it by asking for self.client_address which returns a tuple like Name of client that sent request: ('127.0.0.1', 57547).
Is there a way to ask for an attribute of the object that initiated the connection?
No. You would have to send that name over the communication channel.
I want to connect Blender (v2.55) to a webpage through sockets.
For the web part, I can use Node.js & socket.io. I've already used a little node.js/socket.io, it's not a problem I think.
Now for Blender, it runs on Python 3.1, so I've already sockets and I can add libraries if needed. I'm new to Python sockets, can I connect a client to node.js/socket.io directly ?
I tried with the basic code from the Python doc:
import socket
import sys
HOST, PORT = "127.0.0.1", 8080
data = "Hello from Blender"
# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to server and send data
sock.connect((HOST, PORT))
sock.send(bytes(data + "\n","utf8"))
# Receive data from the server and shut down
received = sock.recv(1024)
sock.close()
print("Sent: %s" % data)
print("Received: %s" % received)
It results by:
Sent: Hello from Blender
Received: b''
It seems that Blender is connected, but doesn't receive data. Also Node shows no new client connected…
Do I need something else ? If somebody can help me out…
You are missing a protocol/handshake. What you have there is a bare TCP socket connection. node.js/socket.io lives on top of a TCP socket. Basically when you open a connection to a socket.io server, it's expecting you to use some protocol for communication (websockets, longpolling, htmlfile, whatever). The initial handshake defines what that protocol will be. Websockets is one of the supported protocols. This blog post should help you. It doesn't look all that hard to get websockets implemented.
you can try the form of loop to receive valid data.
import socket
host="127.0.0.1"
port=8088
web=socket.socket()
web.bind((host,port))
web.listen(5)
print("recycle")
while True:
conn,addr=web.accept()
data=conn.recv(8)
print(data)
conn.sendall(b'HTTP/1.1 200 OK\r\n\r\nHello world')
conn.close()
and use your browser to visit the host and port for a check
I understand this thread is extremely old. But I faced the same problem recently and couldn't find an answer or any similar questions. So here is my answer.
Answer: Use socket.io for python python-socketio
The reason why built-in sockets or any other websocket library in python won't work is explained in the socket.io website socket.io
Socketio is simply just not a websoket connection. Although they say, it uses websockets for transport internally, the connection is established with HTTP protocol http:// as opposed to the WEBSOCKET protocol ws://. This results in the failure of handshake and the connection fails to be established.