Hobbyist. Going through Lutz's 'Programming Python' on sockets/servers. Intermediate level of python knowledge but almost no knowledge of network programming.
The first example runs a server and client scripts that I can get running on my own pc using 'localhost', but I would like to run the server on a remote machine.
I set up an AWS account and an instance of EC2 and an instance of Cloud 9.
The terminology for the different web services gets too confusing for me from here. I tried playing around with permissions on the security groups page, and I can get the script running on Cloud 9, but I can't connect to it from my PC.
If someone could please steer me in the right direction (how do I get this script running via AWS and how do allow external connections to the server to interact with it?) I would be most appreciative!
Thanks.
Server script.
from socket import *
myHost = ''
myPort = 50007
sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.bind((myHost, myPort))
sockobj.listen(5)
while True:
connection, address = sockobj.accept()
print('Server connected by', address)
while True:
data = connection.recv(1024)
if not data: break
connection.send(b'Echo=>' + data)
connection.close()
Client script
import sys
from socket import *
# will change localhost to server IP address, right?
serverHost = 'localhost'
serverPort = 50007
message = [b'Hello network world']
if len(sys.argv) > 1:
serverHost = sys.argv[1]
if len(sys.argv)> 2:
message = (x.encode() for x in sys.argv[2:])
sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.connect((serverHost, serverPort))
for line in message:
sockobj.send(line)
data = sockobj.recv(1024)
print('Client received:', data)
sockobj.close()
Related
I'm reading about socket module in a web learning site about python, they gave us a simple steps to use socket module like follows:
import socket
with socket.socket() as client_socket:
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
data = 'Wake up, Neo'
data = data.encode()
client_socket.send(data)
response = client_socket.recv(1024)
response = response.decode()
print(response)
when executing I got the error message:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it.
when I searched about this some sites was talking about server listening and I see in most of tutorials about server socket and they use it along with client one.
so Is the error message related to the fact that I'm not using a server socket and is it a must to use them both
Update:
after reading the answers I got, I went to the test.py file that the course instructors use to evaluate our codes and I see that they make the server socket in it , so the server is already made by them. that take me back to the Error I got why does it happen then.
def server(self):
'''function - creating a server and answering clients'''
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(('localhost', 9090))
self.ready = True
try:
self.sock.listen(1)
conn, addr = self.sock.accept()
self.connected = True
conn.settimeout(15)
while True:
data = conn.recv(1024)
self.message.append(data.decode('utf8'))
if len(self.message) > 1_000_000:
conn.send(
json.dumps({
'result': 'Too many attempts to connect!'
}).encode('utf8'))
break
if not data:
break
Each connection requires a client, which initiates the connection, and a server, which listens for the incoming connection from the client. The code you have shown is for the client end of the connection. In order for this to run successfully you will need a server listening for the connection you are trying to create.
In the code you showed us you have the lines
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
These are the lines that define what server you are connecting to. In this case it is a server at 127.0.0.1 (which is localhost, the same machine you are running the code on) listening on port 9090.
If you want to make your own server then you can look at the documentation for Python sockets and the particular functions you want to know about are bind, listen, and accept. You can find examples at the bottom of that same page.
Given that you appear to have found this code as part of a course, I suspect they may provide you with matching server code at some point in order to be able to use this example.
recently I've been messing around with sockets in python and i needed to connect to a remote server for a project. I know there are plenty of questions about this topic but none of the solutions worked for me and i am about to go mad if i can't get this to work.
Server code:
import socket
import threading
FORMAT = "UTF-8"
PORT = 55555
SERVER = ''
ADDR = ('0.0.0.0', PORT)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
conn.send("Test".encode(FORMAT))
def start():
server.listen()
print(f"[LISTENING] Server is listening on {PORT}")
while True:
connection, adress = server.accept()
thread = threading.Thread(target=handle_client, args=(connection, adress))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start()
Client Code:
import socket
import threading
FORMAT = "UTF-8"
PORT = 55555
SERVER = "xx.xxx.xxx.xxx" # public ip
print(f"\nconnecting... {PORT}\n")
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect(ADDR)
except:
print("Couldnt connect.")
print(client.recv(1024).decode(FORMAT))
When i change the SERVER variable in client script to my local ip (192.168.1.34), i can run these two scripts in two different pcs in the same LAN and it works well, i recieve the "Test" message in my client pc.
However, when i change the SERVER variable to my public ip and run the server in my server pc, i can't connect to the client pc. Here, my server and client pcs are NOT in the same network. Server is connected to my router whereas client is in another network. When i run the client script nothing happens and after a while i get [WINERROR 10057]
I've done port forwarding to port 55555. I tried disabling all firewalls and even creating a new rule in windows firewall to allow connections from port 55555. It still doesn't work and i can't figure out why.
If there is anyone who can see the problem here i would really appreciate it.
The only thing I can see that maybe is causing a problem is in your ADDR variable. I recently did a similar project that was successful, and in my sever code I did the equivalent of:
ADDR('',PORT)
I don't know for sure this would fix your problem, but it is my best guess from the info you provided.
I Just install linux VM in azure cloud and created a server.py which basically receive data from client.py located at another host and returns capitalize form of data. When i run server.py in my vm its running and when i send data through client.py to the server.py i don't know wether the data transaction occurs or no wether connection is etablished or not, but nothing happens:
client.py:
enter code here
from socket import *
serverName = '13.91.90.71'
serverPort = 12000
clientSocket = socket(AF_INET,SOCK_DGRAM)
message = input('Enter lowercase sentence:')
clientSocket.sendto(message.encode(),(serverName, serverPort))
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
print (modifiedMessage.decode())
clientSocket.close()
server.py:
enter code here
from socket import *
serverPort =12000
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', serverPort))
print('Ready to listen')
while 1:
message,clientAddress = serverSocket.recvfrom(2048)
modifiedMessage = message.upper()
print(modifiedMessage)
serverSocket.sendto(modifiedMessage, clientAddress)
For your issue, the problem is that you need to change the bind of the server like this:
serverSocket.bind(('0.0.0.0', serverPort))
or
serverSocket.bind(('vm_private_ip', serverPort))
The vm_private_ip is the real IP address of the VM. And then you also need to add a rule to the NSG associated with the VM to allow the port 12000.
So I have a Client - Server code in python and its running perfectly on LAN. I have this server setup on AWS and I have uploaded my server code there. In my client code, I have changed the host to the ip-address of the server online.
Unfortunately when I run the server code then the client code, there is no connection established. What could be the issue ??
Here is a part of client code:
def starting_client():
sckt = socket.socket()
host = '172.31.32.226'
port = 9090
sckt.connect((host, port))
while True:
data = sckt.recv(1024) #Data received from the server
try:
Here is part of Server code:
def SeverSocket():
try:
global host
global port
global sckt
host = ''
port = 9090
sckt = socket.socket()
except socket.error as scktCreationErrorMsg:
print(f"An error was encountered during Socket Creation: {scktErrorMsg}")
else:
print("\033[34mSocket was created as succesfull\033[0m")
I am trying to set up a local server so that other PCs on the same local network can connect to it. When trying to do so, on the client side, I get the following error:
[Errno 10061] No connection could be made because the target machine actively refused it
I have been searching around for hours and still couldn't resolve this issue. I tried turning off my Firewall too, but nothing.
These are my server and client codes:
Server Code:
import socket
import threading
import SocketServer
import datetime
ver_codes = []
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
print threading.current_thread().isDaemon()
data = self.request.recv(1024)
command = data.split()[0]
if(command=="login"):
if(logged_in(data.split()[1])==False):
self.request.sendall(login(data.split()[1], data.split()[2]))
else:
self.request.sendall("already in")
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
def client(ip, port, message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
try:
sock.sendall(message)
response = sock.recv(1024)
print "Received: {}".format(response)
finally:
sock.close()
def logged_in(id_num):
for i in ver_codes:
if(i[0]==id_num):
return True
return False
def login(username, password):
login_file = open("Login.txt", "r")
match = login_file.readline()
while(match!="*"):
if(match.split()[0]==username):
if(match.split()[1]==password):
ver_codes.append([match.split()[0], encryption_code(match.split()[2])])
login_file.close()
return "{} {}".format(match.split()[2], encryption_code(match.split()[2]))
print "And Here"
match = login_file.readline()
return "Denied"
login_file.close()
def encryption_code(to_encrypt):
now = datetime.datetime.now()
return int(str(now.microsecond)) * int(to_encrypt)
if __name__ == "__main__":
HOST, PORT = "localhost", 7274
server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
ip, port = server.server_address
print server.server_address
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = False
server_thread.start()
print "Server loop running in thread:", server_thread.name
Client Code:
import socket
import sys
HOST, PORT = "localhost", 7274
data = " ".join(sys.argv[1:])
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
sock.sendall("login mahdiNolan m1373")
received = sock.recv(1024)
finally:
sock.close()
I really appreciate any help you could give me!
Thanks A LOT beforehand!
Your issue is because you're listening on localhost - this will only accept connections from the local machine.
If you want to accept connections from anywhere, instead of "localhost" just pass the empty string "". This is equivalent to specifying INADDR_ANY to the C sockets API - see the ip man page for more information, or this page also looks like it has some useful explanation. In short, this means "accept connections on any local interface".
Instead of the empty string you can instead specify an IP address of a local interface to only accept connections on that interface - it's unlikely you need to do this unless you machine has multiple network cards inside it (e.g. acting as a gateway) and you only want to serve requests on one of the networks.
Also, on the client side you should use the actual address of the machine - replace "localhost" with the IP address or hostname of the server machine. For example, something like "192.168.0.99". If you want to find the IP address of the server under Windows, open a DOS window and run the ipconfig command, look for the line with IPv4 Address (assuming you've got an IPv4 network which is very likely).
The Windows firewall will also block the server from accepting connections as you've already found, but you shouldn't need to disable it - as soon as you run your server you should see a popup window where you can instruct it to accept connections (that was on Windows 7, it might be different on other versions). In any case, turning the software firewall off should allow everything to work, although whether that's a security risk is a matter outside of the scope of this question.