I am trying to create a simple web server in python. I've imported the two modules I needed but I keep getting 'undefined name' error for AF_INET and SOCK_STREAM. I am fairy new to this so any help would be appreciated.
from socket import socket
import sys
serverPort = 6789
serverSocket = socket(AF_INET, SOCK_STREAM)
Having Context managers while dealing with Python sockets is safer and better approach, you can do it like that:
import socket
import sys
serverHost = '127.0.0.1'
serverPort = 6789
## Context manager to allow you to allocate and release resources
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
## Bind it to the specified IP and PORT
s.bind((serverHost, serverPort))
## Listen on the server port to enable accepting connections
s.listen()
## Then accept connections to the server
conn, add = s.accept()
Related
Here is the error that it is showing
I use windows 7 running python 3.8.6. But it is showing that socket module does not have socket.bind.
you must create socket object first. then you can call socket.bind which state the 'socket' or 's' here as an object, as this example
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
Try socket.socket.bind instead.
Or change import to from socket import socket
I am working on a python program which will allow me to send and receive data between PCs. I have managed to get it to work in my local network and wanted to set it up to be able to connect from the internet. I opened the port 1234 in my router and used the local IP on the server.py and puclic IP on the client, but the server.py seems to not receive any data. What am I doing wrong here?
The example code is something like this (it works for local networks, but on separate PCs only, IP address, of course, is just an example and probably will not work for anyone else):
server.py:
import socket
import time
import pickle
IP = "192.168.1.69"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen()
print(f'Listening for connections on {IP}:{PORT}...')
client_socket, client_adress = server_socket.accept()
print(pickle.loads(client_socket.recv(1024)))
client_socket.send(pickle.dumps('DONE'))
time.sleep(1)
client_socket.send(pickle.dumps('boi'))
print(client_socket, client_adress)
client.py:
import socket
import pickle
import time
IP = "192.168.1.69"
PORT = 1234
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)
client_socket.send(pickle.dumps("NICE."))
time.sleep(1)
print(pickle.loads(client_socket.recv(1024)))
time.sleep(1)
print(pickle.loads(client_socket.recv(1024)))
Thank you.
There is something i can't get my head arround. I've created a unix datagram socket with:
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
self.socket.bind(SOCKET_FILE)
Later in the code i receive messages written to the socket with
data, addr = self.socket.recvfrom(4096)
But addr appears to be None all the time. But i need it to send back a response.
How can i achieve writing back to the sender with unix datagram sockets?
Thank you for your answers
Suppose we have a server:
# server.py
import os
import socket
SOCKET_FILE = "mysocket-server"
s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
s.bind(SOCKET_FILE)
data, addr = s.recvfrom(4096)
s.close()
os.unlink(SOCKET_FILE)
print(data, addr)
If a client connects and sends a message without binding its own name to the socket, like so:
# client.py
import socket
SOCKET_FILE = "mysocket-server"
sk = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sk.sendto("hello", SOCKET_FILE)
sk.close()
then the message will be sent anonymously with no address bound on the client side (i.e., with addr == None). Note that this is different from IP datagram sockets which are automatically bound to a fresh address (i.e., host address and port number) as soon as you send data.
For such anonymous messages over Unix datagram sockets, the client has no assigned address, and there is no mechanism by which the server can send return data to the sender.
The simplest solution is for the client to bind it's own private name to the socket:
# client2.py
import os
import socket
SERVER_FILE = "mysocket-server"
CLIENT_FILE = "mysocket-client"
sk = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sk.bind(CLIENT_FILE)
sk.sendto("hello", SERVER_FILE)
data, addr = sk.recvfrom(4096)
print(data,addr)
sk.close()
os.unlink(CLIENT_FILE)
Then, using the following modified server:
# server2.py
import os
import socket
SOCKET_FILE = "mysocket-server"
s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
s.bind(SOCKET_FILE)
data, addr = s.recvfrom(4096)
if addr is not None:
s.sendto("world", addr)
print(data, addr)
s.close()
os.unlink(SOCKET_FILE)
you can see that two-way communication is possible.
On Linux, there's an "abstract namespace" extension (see the unix(7) manpage) which means the client can also bind to an empty name with sk.bind(""), like so:
# client3.py
import socket
SERVER_FILE = "mysocket-server"
sk = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sk.bind("")
sk.sendto("hello", SERVER_FILE)
data, addr = sk.recvfrom(4096)
print(data,addr)
sk.close()
This automatically binds the client to a fresh "abstract socket address", which sort of emulates what IP datagram sockets already do.
As an alternative approach, you can use SOCK_SEQPACKET in place of SOCK_DGRAM. This automatically constructs a two-way connection (like SOCK_STREAM) but preserves the message boundaries (like SOCK_DATAGRAM). Here's a server that accepts connections from clients in a loop, receiving and responding to two packets from each client.
# server4.py
import os
import socket
SOCKET_FILE = "mysocket-server"
s = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
s.bind(SOCKET_FILE)
s.listen(5)
try:
while True:
(t, _) = s.accept()
print(t.recv(4096))
t.send("sun")
print(t.recv(4096))
t.send("moon")
t.close()
finally:
os.unlink(SOCKET_FILE)
The following client demonstrates that the response packets are kept separate:
# client4.py
import socket
SERVER_FILE = "mysocket-server"
sk = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
sk.connect(SERVER_FILE)
sk.send("hello")
sk.send("goodbye")
print(sk.recv(4096))
print(sk.recv(4096))
sk.close()
Here, server4.py isn't a great server design, since a badly behaved client can block, preventing the server from serving any other clients. A real server might use separate worker threads to keep running in the face of slow clients.
You need to bind (to a different socket) on both sides.
A socket isn't automatically created for you, hence the server program doesn't get a name to respond to.
>>> from socket import *
>>> sk=socket(AF_UNIX,SOCK_DGRAM,0)
>>> sk.bind('/tmp/abc')
>>> sk.recvfrom(1024)
('hello', '/tmp/abc1')
>>> from socket import *
>>> sk=socket(AF_UNIX,SOCK_DGRAM,0)
>>> sk.bind('/tmp/abc1')
>>> sk.sendto('hello','/tmp/abc')
5
I've got this code at the moment, it's a simple socket server:
import socket
import time
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 9999
serversocket.bind((host, port))
serversocket.listen(5)
while True:
clientsocket,addr = serversocket.accept()
print(str(addr) + "connected")
test = "Package"
clientsocket.send(test.encode('utf-8'))
clientsocket.close()
I also made a client that gets the message. However, how do I make it so that when I type in the address of my socket on for example Chrome, it displays "Package". I have basic knowledge on handlers and such, but I can't find any DIY websocket tutorials on the internet.
I do not want to use for example tornado, I want to make a simple one myself
Thank you very much in advance!
I'm trying to make simple Client-Server program but it's only working when I'm running both scripts on same computer, when moving it to other computer - It does not make connection at all.
Server:
__author__ = 'user-pc'
import socket # Import socket module
s = socket.socket() # Create a socket object
host="0.0.0.0" # Bind with everyone
port = 13254 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close() # Close the connection
Client:
__author__ = 'user-pc'
import socket # Import socket module
s = socket.socket() # Create a socket object
host = "192.168.10.4" # Server Ip
port = 13254 # Reserve a port for your service.
s.connect((host, port))
print s.recv(1024)
s.close # Close the socket when done
Can you please help me to figure the problem?
Thanks.
As it works when you run both scripts on the server it is likely your port is closed.
Verify your port is open. Go to this website: http://www.canyouseeme.org/
Enter your port and IP. It is highly likely your port is closed. This will verify that. Assuming your port is open you need to look into your firewall settings as reccomended by dmg in the comment above. Then, it is no longer a python issue!