so i tried to make a simple chat room with python 3.8 , with a simple twist that instead of having one server and tow client connecting to that server , the conversation goes on between a client and the server it self , the code worked completely as intended on a single machine and also on tow different devices on a local network ( both connected to the same router and modem ) , but when i tried to access it on a different device out of the local network , client could not connect to the server , here is my code for the server side :
import socket
import threading
FORMAT = "utf-8"
PORT = 9999
HOST_IP = '192.168.1.56'
print("[SERVER STARTING]")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST_IP, PORT))
server.listen()
def accepting():
global connection
print('[WAITING FOR CONNECTION ... ]')
while True:
connection, address = server.accept()
print(f'[NEW CONNECTION] {address} Connected to the server ')
connection.send(f"[SERVER] Welcome to {HOST_IP}".encode(FORMAT))
def receiving():
global connection
while True:
try:
msg = connection.recv(2048).decode(FORMAT)
if len(msg) == 0:
pass
else:
print('[CLIENT] ' + msg)
except:
pass
def sending():
global connection
while True:
try:
server_msg = input("> ")
connection.send(server_msg.encode(FORMAT))
except:
pass
receiving_th = threading.Thread(target=receiving)
accepting_th = threading.Thread(target=accepting)
sending_th = threading.Thread(target=sending)
accepting_th.start()
receiving_th.start()
sending_th.start()
i tried changing the HOST_IP on line 6 to all of the following :
HOST_IP = ''
HOST_IP = '0.0.0.0'
HOST_IP = '127.0.0.1'
neither of them worked . i also tried putting my Public IP address but the following error poped up :
Traceback (most recent call last):
File "C:\Users\pc\PycharmProjects\PrivateMssg1.0\Server.py", line 9, in <module>
server.bind((HOST_IP, PORT))
OSError: [WinError 10049] The requested address is not valid in its context
on the client side , here is my code :
import socket
import threading
FORMAT = "utf-8"
PORT = 9999
HOST_IP = "192.168.1.56"
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST_IP, PORT))
msg = client.recv(2048).decode(FORMAT)
print(msg)
def receiving():
while True:
try:
msg = client.recv(2048).decode(FORMAT)
print('[SERVER] ' + msg)
except:
pass
def sending():
while True:
try:
client_msg = input("> ")
client.send(client_msg.encode(FORMAT))
except:
pass
receiving_th = threading.Thread(target=receiving)
sending_th = threading.Thread(target=sending)
receiving_th.start()
sending_th.start()
i tried my Public IP address here on line 6 HOST_IP = "my public IP" as well but it didnt work .
i researched about 2 days and tried disabling my PC s firewall and my router firewall but that didnt work either .
i also tried opening port 9999 on my pc and also Port Forwarding port 9999 on my router to my local ip 196.168.1.56 . i tried restarting my router and my pc . but none of them worked . i dont think my code is causing it to not connect because it worked fine on a local network . can anyone help me out ?
and can someone try ,y code on their setup ? because the problem might be with my router not port forwarding correctly .
the problem was with my public IP , you need a static public IP to be able to accept inbound request, it worked fine on a linux based server .
Related
I've been making a reverse shell application and since now only tried it on the same machine instead of a different one. Everything works fine as expected when using the same machine but when I try two different machines, the machine on which client.py runs gives me a ConnectionsRefusedError.
The client.py code
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def send(s: socket.socket, obj):
s.send(dumps(obj))
def recv(s: socket.socket):
return loads(s.recv(1024 * 1000))
while True:
try:
server.connect(("server ip", 6969))
connected = True
except:
connected = False
try:
key = recv(server)
if key:
send(server, None)
else:
connected = False
except:
connected = False
loc = my_loc
while connected:
# reverse shell script
Here is the server.py code
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("0.0.0.0", 6969))
server.listen()
def listen():
global server
while True:
conn, addr = server.accept()
clients[addr[0]] = {"conn": conn, "cmd": {"head": None}, "info": {}, "ping": 0, "allowed": True}
logs[addr[0]] = []
shells[addr[0]] = []
client_threads[addr[0]] = Thread(target=_client, args=(addr[0],))
client_threads[addr[0]].start()
listener = Thread(target=listen, name="Listener")
listener.start()
Thats not the whole code, but the part where I get the errors from.
I had this problem multiple times but always somehow fixed it by moving the server = socket.socket() part in server.py around.
Is there anything I'm not seeing here?
Ip for different computers are different.
you will have to check the Ip of the new computer.
I had the same problem:-
If you are connected via the same router the Ip will look like 192.168.**.*
you need this code to get the router IP
import socket
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
print(f"Hostname: {hostname}")
print(f"IP Address: {ip_address}")
If you are doing socket on a different network then you need to change the router settings to do port forwarding.
it is different for different routers so look it up.
Then find your public Ip and change your Ip in the client script.(Do not change IP on server script)
How could we establish connection between server and client through socket programming(Python) with server and client on different devices and on different networks? When we create socket with i/p addr and port
of server, server and client gets connected if both devices are connected on same network. But this is not the case with different networks. What needs to be done to connect them?
import socket
def server_program():
host = socket.gethostname()
port = 5000
server_socket = socket.socket()
server_socket.bind((host, port))
server_socket.listen(2)
conn, address = server_socket.accept()
print("Connection from: " + str(address))
while True:
data = conn.recv(1024).decode()
if not data:
break
print("from connected user: " + str(data))
data = input(' -> ')
conn.send(data.encode())
conn.close()
if __name__ == '__main__':
server_program()
import socket
def client_program():
host = socket.gethostname() // used ngrok i/p here
port = 5000 // used ngrok port no
client_socket = socket.socket()
client_socket.connect((host, port))
message = input(" -> ")
while message.lower().strip() != 'bye':
client_socket.send(message.encode())
data = client_socket.recv(1024).decode()
print('Received from server: ' + data)
message = input(" -> ")
client_socket.close()
if __name__ == '__main__':
client_program()
To establish a connection between server and client on different networks you either need to use port forwarding or you can take help of some external software like ngrok
How do you use ngrok ?
First of all you need to sign up.
Download the ngrok software
Now you would get a screen like this
Copy the line ./ ngrok authtoken .........
Open up cmd and cd into the folder where you've downloaded ngrok
Paste the copied commmand (Note- If you're on windows remove the ./ from starting of the command) and hit enter
Enter the following command
ngrok tcp [Port on which your server is listening]
For example - If your server is listening on port 65432 then you'd have to enter the following command
ngrok tcp 65432
You should now be seeing a window like this
Copy the x.tcp.ngrok...... from the window (highlited in the image above)
Open up cmd and type ping [copied text here]
The output should be something like this :
Pinging x.tcp.ngrok...... [ip here] with 32 bytes of data:
....
....
....
Copy the ip
Now in your client.py file replace the ip with the ip you copied
Copy the port from the ngrok window (Next to the highlighted text in the image above, in my case it's 11171)
Replace the port in client.py file with the port you copied
In server.py change the host to "0.0.0.0"
You're all set to go now! Clients can now connect to your server from all over the globe
I am trying to connect multiple computers with sockets. I can run host and client on my computer, and they will connect. But if i try to run client on another computer, it wont connect. This is my host code:
import socket
import requests
# NOTES:socket.gethostname()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 1234))
s.listen(5)
print("Searching for available computers...")
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established!")
usr = input("Temporary username for this session: ")
msg = input("Send to client: ")
clientsocket.send(bytes(usr + " says > " + msg, "utf-8"))
break
while True:
msg1 = input("Send to client: ")
clientsocket.send(bytes(usr + " says > " +msg1, "utf-8"))
#w
and this is my code for client:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1234))
while True:
msg = s.recv(1028)
print(msg.decode("utf-8"))
what is wrong?
That is because the IP address the server is listening on, is 0.0.0.0 (localhost) only programs on the same computer can access that IP address. Change the IP address from the server to socket.gethostbyname(socket.gethostname()) that will return the local IP address of your computer. And that local IP address can be accessed by anyone, who is connected to the same network. In the code of the client, you have to change the IP address to the IP address, returned from the function above. So run print(socket.gethostbyname(socket.gethostname()))on the server computer and set the IP address the client is connecting to, to the printed value.
The "0.0.0.0" part is correct (keep in mind that this config allows any ip address to connect to the server (from WAN and from LAN)).
You have to change this:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1234))
while True:
msg = s.recv(1028)
print(msg.decode("utf-8"))
into this:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("ip of the server", 1234))
while True:
msg = s.recv(1028)
print(msg.decode("utf-8"))
Because the socket.gethostname() command is meant to get the ip address of the machine you are running the program on (not the server itself... infact if not specified there is no way the client can know on what address the server is located)
p.s.
remember to open port 1234 on the server machine
+
please don't use 1028... that's a very bad number: use 1024 instead
I am learning how to use python sockets right now, and now I am trying to use the simple chat program that I created to talk with one of my friends. of course, the porgram didnt work because I didnt port forward it.
I have forwarded port 21342 using the ip (the ip is static) I found at whatismyip.com as my external ip and the ip shown as the ipv4 in the oputput of the ipconfig command in the cmd as the internal ip.
now, even after forwarding it still isnt working. am I still missing something obvious or is this a real issue?
code:
server:
import socket
import threading as thread
sock = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
host = ''
sock.bind((host , 21342))
sock.listen(5)
connections = []
def chat(client , address):
global connections
while True:
info = client.recv(1024)
for connection in connections:
if connection != client:
connection.send(info)
if not info:
connections.remove(client)
client.close()
break
try:
while True:
client , address = sock.accept()
print 'new connection!'
client_thread = thread.Thread(target = chat , args = (client , address))
client_thread.daemon = True
client_thread.start()
connections.append(client)
sock.close()
except:
for connection in connections:
connection.close()
sock.close()
client:
import socket
import threading as thread
sock = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
host = 'ip found at whatsmyip.com'
sock.connect((host , 21342))
def get_info(sock):
while True:
print sock.recv(1024)
get_info_thread = thread.Thread(target = get_info , args = [sock])
get_info_thread.daemon = True
get_info_thread.start()
while True:
sock.send(raw_input())
sock.close()
I'm trying to set up communication between me and my friend's computer using the socket module. I run the server code on my computer and he runs the client code on his computer. Here is the code:
Server:
import socket
host = "XXX.XXX.XX.XXX" # IP of my computer
port = 2000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
addrs = []
print("Server started")
while True:
data, addr = s.recvfrom(1024)
if not addr in addrs:
addrs.append(addr)
data = data.decode("utf-8")
print("Recieved: " + str(data))
print("Sending: " + data)
for add in addrs:
s.sendto(data.encode("utf-8"), add)
Client:
import socket
import time
host = "XXX.XXX.XXX.XXX" # External IP of my router
port = 2001
server = (host, port)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setblocking(False)
while True:
message = "Test message"
time.sleep(1)
print("Sending: " + message)
s.sendto(message.encode("utf-8"), server)
try:
data, addr = s.recvfrom(1024)
except BlockingIOError:
pass
else:
data = data.decode("utf-8")
print("Recieved: " + str(data))
Note: The port in the client vs. server code is different to make sure that my port forwarding is actually doing something.
I have set up port forwarding on my router. Everything works fine when I run both scripts on my computer (or even another computer connected to the same WiFi as mine) and I know that the port forwarding is doing its thing. However, when my friend (who is connected to a different WiFi) runs the client code, it doesn't work. No error is thrown, but he sends data which neither my computer nor the router's port forwarding rule recieves.
Could this problem originate from my code, or is it more likely to be because of my router not being properly set up?
Okay I setup a HotSpot my Android Phone. which in this case is your "Router", used my phone's IP Address. and On the computer tried to run your client code, its sending test messages on the client:
Sending: Test message
Sending: Test message
Sending: Test message
Sending: Test message
....
but I'm receiving nothing on your Server, still saying server started.
so I configured your host variable on the "Client App" like so, also your ports are not consistent 2000 on server and 2001 on client:
host = "" # External IP of my router
port = 2000
NOTE!! I left the host Empty
Because I think for some reason the server is hosted locally on the pc, you are running the server on. This way i can also Connect locally from the same computer I ran the server app with:
host = "localhost" # External IP of my router
on the your client app.
this is how everything looks.
Server Code
run this on your comuter.
import socket
host = "" # IP of my computer
port = 2000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
addrs = []
print("Server started")
while True:
data, addr = s.recvfrom(1024)
if not addr in addrs:
addrs.append(addr)
data = data.decode("utf-8")
print("Recieved: " + str(data))
print("Sending: " + data)
for add in addrs:
s.sendto(data.encode("utf-8"), add)
Depending on where you ran your serverApp. use the IP of the computer running the server. I'm Still learning so I don't know how to set it up to use your router's IP.
ClientApp Code
run this on your friend computer or more. or on android even.
import socket
import time
host = "ip_of_the_computer_the_server_is_running_on" # connecting from another computer
#host = "localhost" # If you connecting locally
port = 2000
server = (host, port)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setblocking(False)
while True:
message = "Test message"
time.sleep(1)
print("Sending: " + message)
s.sendto(message.encode("utf-8"), server)
try:
data, addr = s.recvfrom(1024)
except BlockingIOError:
pass
else:
data = data.decode("utf-8")
print("Recieved: " + str(data))
And use Your router only for same AP Connection.
Tested with my TOTO-LINK IT WORKS FINE. as long as I don't use my router's IP On the client host.
Demonstrations
Server
CLient
Client On Mobile
This code is actually 100% correct, the error was in my port forwarding.