I am running a UDP server and client (python). When within the same local network, the client is able to talk to the server. However when the server IP address is set to IP address of the router (which has UDP port forwarding to the server), the client is not able to talk with the server at all. I am wondering if anyone can point out why this works within the local network (on different machines) but I cannot make the client connect to the server using external IP address of the router to which both the client and server are connected.
The code for the client
import socket
import sys
HOST, PORT = "<IP address of router which is port forwarded to server>", 5000
data = " Hello from Client" #.join(sys.argv[1:])
# SOCK_DGRAM is the socket type to use for UDP sockets
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# As you can see, there is no connect() call; UDP has no connections.
# Instead, data is directly sent to the recipient via sendto().
sock.sendto(data + "\n", (HOST, PORT))
received = sock.recv(1024)
print "Sent: {}".format(data)
print "Received: {}".format(received)
Code for the server
import SocketServer
class MyUDPHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
socket = self.request[1]
print "{} wrote:".format(self.client_address[0])
print data
socket.sendto(data.upper(), self.client_address)
if __name__ == "__main__":
HOST, PORT = "<local IP address of server", 5000
server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
server.serve_forever()
OK i figured out what was going on.
Router is connected to two computers - Computer A and Computer B. Computer A can talk to Computer B using the local network (UDP server client). However when Computer A (UDP client) sends data to Computer B (UDP server) using the Router IP address (external IP address) with the router port forwarding to Computer B, it was not working. Apparently the server will only accept connections that originate outside the local network when the client uses the external IP address
Related
I'm coding in Python and I'm looking for a way to connect to a website port using sockets so that I can send commands to the server. My code is:
import socket
HOST = 'www.google.com'
PORT = 80
server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen(5)
This code is giving me an error "The requested address is not valid in its context". How do I do this?
You're trying to bind on Google's IP, which doesn't make sense because there isn't a network adapter connected to your computer with that IP (thus the error). You're mixing up creating a server and being a client connecting to a remote server. You want to connect to the Google server:
import socket
HOST = 'www.google.com'
PORT = 80
socket = socket.socket()
socket.connect((HOST, PORT))
# Send an HTTP GET request to request the page
socket.send(b"""
GET / HTTP/1.1
Host: www.google.com
""")
msg = socket.recv(8192)
print(msg)
First of all I am not talking about a tcp or udp or socket implemented in a vps or server
My question is just like client to client socket communication.
Imagine listening at your home pc with a tcp socket. You can connect to this from home inter network anyway. But suppose someone wants to connect to it via the internet. Then you can create a forwarding rule on the router and bring it to working condition. Then the router knows that if an incoming connection comes from a port, the connection will be forwarded to the device in the relevant inter network.
But the ISP I use does not support port forwarding.
I thought these were not impossible because of the team-viewer software. Because when I was connected to a friend in team-viewer, I opened the wire-shark and reviewed it.
Then I saw that the data packet is exchanged peer to peer. Because the destination source addresses were my ip and friend's ip
This means that the video data is exchanged without the participation of an additional server
I highlighted the team-viewer connection.
61.245.175.81 is my friend's public IP. 192.168.1.130 is my internal IP
I want to do the same
Here is my simple socket code. This does not work through the internet because there is no router forwarding rule. I am very new to socket and networking side
Sever
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('', 12000))
while True:
message, address = server_socket.recvfrom(1024)
message = repr(message)
print("Connected from -> " + str(address) )
print("Received data -> " + message)
reply = b"Hi from server :) "
server_socket.sendto(reply, address)
Client
import time , datetime
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.settimeout(1.0)
message = bytes(str(datetime.datetime.now()),'utf-8')
addr = ("192.168.1.130", 12000)
client_socket.sendto(message, addr)
try:
data, server = client_socket.recvfrom(1024)
print( repr(data) )
except: #socket.timeout:
print('REQUEST TIMED OUT')
Can anyone give an explanation for my question
Pretty sure they do it using UDP hole punching, you'd need to do something similar to implement this.
In a nutshell two clients behind NAT (which is what your router is doing) can use a third server acting as a sort of mediator to establish a connection.
I want to create a small TCP server that takes incoming TCP connections from a device that is hooked up via Ethernet to my computer.
The physical port for that has the IP 192.168.1.100 statically assigned to it.
The scripts I use as a client and server are listed at the bottom.
The setup works if I want to send messages between the python scripts. However, I am unable to receive anything from the external device (screenshot from Wireshark capture below). From what I have read I can define an interface to listen to by defining its IP. So I defined the IP of the interface as the host variable. However, I do not receive anything in my script but the messages sent by the other script. I had a similar situation already here on stackoverflow. I thought that defining the correct IP as the host would resolve this issue but it did not.
I am also having a hard time capturing the traffic between the two scripts with Wireshark at all. They did not show up anywhere.
I need to pick up these connections on the eth0 interface with the static IP 192.168.1.100:
tcp_server.py
import socket
# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
# host = socket.gethostname()
host = "192.168.1.100"
port = 9002
# bind to the port
serverSocket.bind((host, port))
# queue up to 5 requests
serverSocket.listen(5)
while True:
# establish a connection
clientSocket, addr = serverSocket.accept()
print("Got a connection from %s" % str(addr))
msg = 'Thank you for connecting' + "\r\n"
clientSocket.send(msg.encode('ascii'))
clientSocket.close()
and this as a client:
tcp_client.py
import socket
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
# host = socket.gethostname()
host = "192.168.1.100"
port = 9002
# connection to hostname on the port.
s.connect((host, port))
# Receive no more than 1024 bytes
msg = s.recv(1024)
s.close()
print(msg.decode('ascii'))
Two computers in a LAN connecting to a wireless router, one IP address is 192.168.1.106 (server), the other one is 192.168.1.107 (client), the gateway on both computer is 192.168.1.1 (the router itself).
The two computer can ping each in two directions which means there should be no problem with routing and the router itself. But I failed when I tried to use Python UDP socket, the server cannot get any information from the client, and same happened when I change the ip address. (But it works fine when server and client are on a same computer using local ip address, so the code is should be ok)
I am using the following code:
server:
import socket
address = ('192.168.1.106', 5678) # the server listening on address 192.168.1.106
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(address)
while True:
data, addr = s.recvfrom(2048)
if data == "empty":
print "no data from client"
else:
print "received:", data, "from", addr
s.close()
client:
import socket
address = ('192.168.1.106', 5678) # the client send to address 192.168.1.106
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
msg = raw_input()
if not msg:
msg = "empty"
s.sendto(msg, address)
s.close()
Did you open the UDP port on the firewall on both comoutera?
I have set up a server socket (plain raw socket) listening on port A. A client now connects to this server. OS opens up a port for the client for this purpose. Say port B is allocated to this client. Now my question is, can a 3rd script connect to this port B and send data. Or in other words can I spoof a response to the client as if it was coming from the server? I tried spoofing it using scapy, but it wasnt working.
server.py
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost", A))
s.listen(10)
ns, cli_addr = s.accept()
time.sleep(30) # so that i can trigger my 3rd script
goodclient.py
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", A))
print s.getsockname() # to get the local port of client - B
s.recv(1024)
badboy.py
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", B)) # connection refused error
s.send("hihihi")
scapybadboy.py
pack = IP(src="localhost", dst="localhost") / TCP(sport=A, dport=B) / "Hello"
send(pack) # Packet sent but not received by the client
Because server and client using SOCK_STREAM sockets, they both aware of TCP session(including port, IP and (SEQ_NUMBER,ACK_NUMBER)), so when session is already in process, you will have to perform TCP hikacking and IP spoofing in order to send messages in stream.
In other words, you will have to guess(or steal) ACK number of server in order to send fake messages to client using badclient.
However, if you will make somehow goodclient answer you and not a server you should run the following:
iptables -A FORWARD -j NFQUEUE --queue-num 1 , because your operating system doesn't know about session that you just "opened" with goodclient and it will send RST packet. This command will prevent it.