I'm making a server and client in Python 3.3 using the socket module. My server code is working fine, but this client code is returning an error. Here's the code:
import socket
import sys
import os
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('192.168.1.5', 4242)
sock.bind(server_address)
while True:
command = sock.recv(1024)
try:
os.system(command)
sock.send("yes")
except:
sock.send("no")
And here's the error:
Error in line: command = sock.recv(1024)
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
What on earth is going on?
It looks like you're confused about when you actually connect to the server, so just remember that you always bind to a local port first. Therefore, this line:
server_address = ('192.168.1.5', 4242)
Should actually read:
server_address = ('', 4242)
Then, before your infinite loop, put in the following line of code:
sock.connect(('192.168.1.5', 4242))
And you should be good to go. Good luck!
EDIT: I suppose I should be more careful with the term "always." In this case, you want to bind to a local socket first.
You didn't accept any requests, and you can only recv and/or send on the accepted socket in order to communicate with client.
Does your server only need one client to be connected? If so, try this solution:
Try adding the following before the while loop
sock.listen(1) # 1 Pending connections at most
client=sock.accept() # Accept a connection request
In the while loop, you need to change all sock to client because server socket cannot
be either written or read (all it does is listening at 192.168.1.5:4242).
Related
What I wanted to do:
For learning about game programming I created an echo setup using a dedicated server and UDP. The dedicated server is in a different city (aka NOT in my local network).
On my local computer I have a udp client and server ( 2 different programs ). When I first started my python server I was immediately asked by windows firewall whether I want to add an exception. After allowing networking for my python server, I still did not receive any messages. (client -> dedicated server -/-> local server )
Only after I set a port forwarding in my router I was able to receive messages on my local UDP server.
My question is:
How do games solve that problem ? I don't activate a port forwarding for each multiplayer game I want to play and I'm still able to receive data in all these games.
My dedicated server setup (address and port intentionally changed):
#!/usr/bin/python3
import socket
ADDRESS = "1.123.123.123"
PORT = 12345
serverSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
serverSock.bind((ADDRESS, PORT))
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addresses = []
while True:
data, addr = serverSock.recvfrom(1024)
if addr not in addresses:
addresses.append(addr)
msg = str(data)
#if msg.split()
print("Message: " + str(data))
outMsg = str(addr) + ":" + msg
for ad in addresses:
print("Send Msg " + outMsg + " to " + ad[0] + ":" + str(PORT))
clientSock.sendto(bytes(outMsg, "utf-8"), (ad[0], 12345))
print("Addresses: " + str(addresses))
I figured this one out while writing up the question (like talking to the good old rubber duck):
The trick is not using 2 programs on the local computer. The program that sends the message also needs to retrieve the message. In my example it's blocking calls (ugly!), for a game you'd want to make that asynchronous. But this is the simplest way to get around the router firewall:
#! /usr/bin/python3
import socket
ADDRESS = "1.123.123.123"
PORT = 12345
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# usually not required to bind a client, but we want to receive messages
clientSock.bind(("0.0.0.0",PORT))
while True:
msg = input("Enter message: ")
# Note that it is not required to send to the same port
# you have locally binded to.
clientSock.sendto(bytes(msg, "utf-8"), (ADDRESS, PORT))
# listen to the echo:
data, addr = clientSock.recvfrom(1024)
print(str(data) + " from " + str(addr))
However, my understanding on sockets and firewalls is limited. I do not understand why THIS works but 2 separated programs don't. Maybe someone could comment on that.
Hope I can save someone some time =)
I was following a tutorial called "Black Hat Python" and got a "the requested address is not valid in its context" error. I'm Python IDE version: 2.7.12
This is my code:
import socket
import threading
bind_ip = "184.168.237.1"
bind_port = 21
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip,bind_port))
server.listen(5)
print "[*] Listening on %s:%d" % (bind_ip,bind_port)
def handle_client(client_socket):
request = client_socket.rev(1024)
print "[*] Recieved: %s" % request
client_socket.close()
while True:
client,addr = server.accept()
print "[*] Accepted connection from: %s:%d" % (addr[0],addr[1])
client_handler = threading.Thread(target=handle_client,args=(client,))
client_handler.start()
and this is my error:
Traceback (most recent call last):
File "C:/Python34/learning hacking.py", line 9, in <module>
server.bind((bind_ip,bind_port))
File "C:\Python27\lib\socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
error: [Errno 10049] The requested address is not valid in its context
>>>
You are trying to bind to an IP address that is not actually assigned to your network interface:
bind_ip = "184.168.237.1"
See the Windows Sockets Error Codes documentation:
WSAEADDRNOTAVAIL 10049
Cannot assign requested address.
The requested address is not valid in its context. This normally results from an attempt to bind to an address that is not valid for the local computer.
That may be an IP address that your router is listening to before using NAT (network address translation) to talk to your computer, but that doesn't mean your computer sees that IP address at all.
Either bind to 0.0.0.0, which will use all available IP addresses (both localhost and any public addresses configured):
bind_ip = "0.0.0.0"
or use any address that your computer is configured for; run ipconfig /all in a console to see your network configuration.
You probably also don't want to use ports < 1024; those are reserved for processes running as root only. You'll have to pick a higher number than that if you want to run an unprivileged process (and in the majority of tutorials programs, that is exactly what you want):
port = 5021 # arbitrary port number higher than 1023
I believe the specific tutorial you are following uses BIND_IP = '0.0.0.0' and BIND_PORT = 9090.
I was just getting this error while following this Python TCP example and the solution was to have my client connect using 'localhost' instead of '0.0.0.0'.
I want to make 2 devices communicate via sockets.
I use this code for the client socket:
Socket socket = Gdx.net.newClientSocket(Net.Protocol.TCP, adress, 1337, socketHints);
(SocketHints: timeout = 4000)
I get a GdxRuntimeException each time this line is being executed. What is wrong with the socket?
Screenshot of stack trace
You get that message because the socket couldn't be opened.
Note the last line about the return in the API:
newClientSocket:
Socket newClientSocket(Net.Protocol protocol,
java.lang.String host,
int port,
SocketHints hints)
Creates a new TCP client socket that connects to the given host and port.
Parameters:
host - the host address
port - the port
hints - additional SocketHints used to create the socket. Input null to use the default setting provided by the system.
Returns:
GdxRuntimeException in case the socket couldn't be opened
Try doing some debugging to find out why you are getting this error.
Is the port already in use? Are you trying to open more than one connection on the same port? Is the server IP valid? Maybe something else is causing the issue?
So I am very new to networking and the Socket module in Python. So I watched some Youtube tutorials and found one on how to write the code for a simple server. My problem is right when the server receives data from the client, the server close() and loses connection to the client right when it receives the data. I want the server to automatically lose connection to the client but not "shutdown" or close(). I want to set it (if its possible) so that while the server is running in my Python Shell, if I want to close() the connection I use hot keys like for example "Control+E"? Here is my code so far:
#!/usr/bin/python
import socket
import sys
# Create a TCP/IP socket to listen on
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Prevent from "adress already in use" upon server restart
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind the socket to port 8081 on all interfaces
server_address = ('localhost',8081)
print ('starting up on %s port %s')%(server_address)
server.bind(server_address)
#Listen for connections
server.listen(5)
#Wait for one incoming connection
connection, client_address = server.accept()
print 'connection from', connection.getpeername()
# Let's recieve something
data = connection.recv(4096)
if data:
print "Recived ", repr(data)
#send the data back nicely formatted
data = data.rstrip()
connection.send("%s\n%s\n%s\n"%('-'*80, data.center(80),'-'*80))
# lose the connection from our side (the Server side)
connection.shutdown(socket.SHUT_RD | socket.SHUT_WR)
connection.close()
print 'Connection closed'
# And stop listening
server.close()
==================================================================================
Here is the code I am using (on the server side):
#!/usr/bin/python
import socket, sys
import select
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Let's set the socket option reuse to 1, so that our server terminates quicker
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("localhost", 8081))
srv.listen(5)
while True:
print "Waiting for a client to connect"
(client, c_address) = srv.accept() #blocking wait for client
print "Client connected"
# Client has connected, add him to a list which we can poll for data
client_list = [client]
while close_socket_condition == 0:
ready_to_read, ready_to_write, in_error = select.select(client_list, [], [] , 1) #timeout 1 second
for s in ready_to_read: #Check if there is any socket that has data ready for us
data = client.recv(1024) # blocks until some data is read
if data:
client.send("echo:" + data)
client.close()
close_socket_condition = 1
And here is the error it is giving me when I try to send a string to the server:
data = s.recv(1024)
File "C:\Python27\lib\socket.py", line 170, in _dummy
raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor
Here is example on a non-blocking socket read with similar structure as yours.
The server will establish a socket in localhost, and wait for a client to connect. After that it will start polling the socket for data, and also keep checking the exit condition close_socket_condition. Handling ctrl-e or other exit events will be left as an exercise :)
First we start socket, very much the same way as you:
#!/usr/bin/python
import socket, sys
import select
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Let's set the socket option reuse to 1, so that our server terminates quicker
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("localhost", 8081))
srv.listen(5)
Then we declare our external exit condition close_socket_condition, and start eternal while loop that will always welcome new clients:
close_socket_condition = 0
while True:
print "Waiting for a client to connect"
(client, c_address) = srv.accept() #blocking wait for client
print "Client connected"
Now a client has connected, and we should start our service loop:
# Client has connected, add him to a list which we can poll for data
client_list = [client]
while close_socket_condition == 0:
Inside the service loop we will keep polling his socket for data and if nothing has arrived, we check for exit condition:
ready_to_read, ready_to_write, in_error = select.select(client_list, [], [] , 1) #timeout 1 second
for s in ready_to_read: #Check if there is any socket that has data ready for us
data = client.recv(1024) # blocks until some data is read
if data:
client.send("echo:" + data)
client.close()
close_socket_condition = 1
This code is simplified example, but the server will keep accepting new clients, and always reuse the connection. It does not handle client side terminations etc.
Hope it helps
I have a simple Python server which can handle multiple clients:
import select
import socket
import sys
host = ''
port = 50000
backlog = 5
size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host,port))
server.listen(backlog)
input = [server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == server:
# handle the server socket
client, address = server.accept()
input.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
data = s.recv(size)
if data:
s.send(data)
else:
s.close()
input.remove(s)
server.close()
One client connects to it and they can communicate. I have a third box from where I am sending a RST signal to the server (using Scapy). The TCP state diagram does not say if an endpoint is supposed to try to recover a connection when it sees a RESET. Is there any way I can force the server to recover the connection? (I want it to send back a SYN so that it gets connected to the third client)
Your question doesn't make much sense. TCP just doesn't work like that.
Re "The TCP state diagram does not say if an endpoint is supposed to try to recover a connection when it sees a RESET": RFC 793 #3.4 explicitly says "If the receiver was in any other state [than LISTEN or SYN-RECEIVED], it aborts the connection and advises the user and goes to the CLOSED state.".
An RST won't disturb a connection unless it arrives over that connection. I guess you could plausibly forge one, but you would have to know the current TCP sequence number, and you can't get that from within either of the peers, let alone a third host.
If you succeeded somehow, the connection would then be dead, finished, kaput. Can't see the point of that either.
I can't attach any meaning to your requirement for the server to send a SYN to the third host, in response to an RST from the third host, that has been made to appear as though it came from the second host. TCP just doesn't work anything like this either.
If you want the server to connect to the third host it will just have to call connect() like everybody else. In which case it becomes a client, of course.