Why cant my friend not connect to my socket - python-3.x

so im trying to establish connection between my friends pc and my pc but it keeps saying the host failed to respond
this is the client
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.0.177", 1234))
msg = s.recv(1024)
print(msg.decode("utf-8"))
and this is the server
import socket
s = socket.socket(socket.AF_INET
, socket.SOCK_STREAM)
s.bind(('192.168.0.177', 1234))
s.listen(5)
while True:
clientsocket, address = s.accept()
print(f'conection from {address} has bene establish')
clientsocket.send(bytes("welcome to the server", "utf-8"))
Update/Edit
so i tried my public IP address and it says
WinError 10049] The requested address is not valid in its context
the error is serverside

In the comments, you say that your friend is on a different LAN as you. The reason that he can not reach your server is because he is trying to reach your server on your LAN by connecting to an address (192.168.0.177) in the 192.168.x.x. space from his LAN.
See https://en.wikipedia.org/wiki/Private_network, where it explains that addresses in the 192.168.0.0 – 192.168.255.255 range are reserved for private networks. As such, IP packets originating from or addressed to a private IP address cannot be routed through the public Internet.
To solve this problem, you should setup a port-forwarding rule your router, to forward incoming connections to port 1234 on the public side of your router to 192.168.0.177:1234 on the private side of your router. Then, your friend should connect to xxx.xxx.xxx.xxx:1234, where xxx.xxx.xxx.xxx is the public IP address of your router. You can find the public ip address of your router by pointing your web browser to www.whatismyip.com from a computer on your LAN. If the port-forwarding is working correctly, your router should forward the incoming connection from your friend to your server at 192.168.0.177:1234 running on your private LAN.

The IP range 192.168.0.0 to 192.168.255.255 (192.168.0.0/16) is considered to be the private range. Even if you design your routers to force the packets from these sources to the outside internet world, other routers will be discarding the packets.
You need to have both the machines on the same LAN or you need to set up a network on your own and configure routers (routing tables) in between or a public IP for accepting connections.

Related

How does application running on arbitrary port get packets from Internet?

while I was studying Internet Protocols, a question just occurred to me. Typically, we could assign any ports that are not for typical usage (e.g. 80 for HTTP, 443 for HTTPS) to our applications. For example, when I use Node.js Express to build a simple server, I could assign port 5000 to this process like below.
const express = require('express')
const app = express()
const port = 5000
// some code to configure server
app.listen(port, () => {
console.log(`Server is now running on port ${port}`)
})
My Node.js application will listen to port 5000. If my ip is for example 10.10.10.10, then my application will get a request if anyone hits 10.10.10.10:5000. However, if that's a HTTP/HTTPS request, shouldn't the packets come from port 80 / 443? Can someone tell me why it's not the case or why application listening to different ports can receive packets if they indeed come from 80 / 443.
Thank you.
When a packet leaves your computer it went through all the layers of the OSI model. It contains basically six specific information.
The destination and source IP address (the IP address of the server and your IP address respectively), the destination and source port (the port it is destined to at the server and the port it uses on your machine) and the destination and source MAC address (the MAC address of the machine it is destined to (locally) and the MAC address of your computer).
In a simple configuration (the computer behind a router), when you send this packet, it will be rerouted to the router using it's MAC address. The OS keeps a routing table which has the info on what to do with what IP address. Whether it is "On-Link" or if it needs to send the packet to a default gateway. You can print the routing table of your computer by typing route print in Windows CMD. If you are joining an outside server then the packet will be sent to the default gateway. It may need to do an ARP request in order to get the MAC address of the default gateway (or not depending on your computer's ARP table at that moment). You can see the ARP table by typing arp -a on Windows (in CMD).
Once the packet reaches the router, the router strips off the source IP (your internal network IP) and replaces it with the IP of it's external interface (your public IP). It does the link between those two addresses using the NAT table:
It also strips off the internal port and replaces it with a random available port (to the right). It means that 2 different machines accessing the same website can share the same local port. The destination port stays the same.
In the end if you receive a request from outside your router. Your router doesn't have a NAT table entry for that packet because it wasn't initiated by you. You'll need to use port forwarding to tell your router to forward incoming packets (destined to a certain port) to a certain internal IP.
Some routers (like mine) don't support specifying an external port AND an internal port. So both of these are the same (you cannot specify a different external vs internal port so you can't forward external 80 to internal 5000). In your case, you would need to specify an external port of 80/443 and an internal port of 5000 destined to 10.10.10.10 for your configuration to work. Otherwise, it should not work.

Why is "connection refused" error occuring

This is client.py class and This class is on mobile.
import socket
c = socket.socket()
c.connect(('127.0.0.1', 9998))
name = input("Enter your name : ")
c.send(bytes(name, 'utf-8'))
data = c.recv(1024).decode()
print(data)
This is server.py class and This class is on mac book pro.
import socket
s = socket.socket()
s.bind(('localhost', 9998))
s.listen(2)
print('server is waiting for connections..')
while True:
c, addr = s.accept()
name = c.recv(1024).decode()
print('connected with', addr, name)
st = "Hello, " + name
c.send(st)
c.close()
Why am I getting "connection refused" error?
Your client and server are running on different devices. Your client is trying to connect to the local loopback IP 127.0.0.1, which will work only if the server is running on the same device as the client. That is why you are getting "connection refused" - there is no server listening locally at 127.0.0.1:9998.
If the client and server are connected to the same network (WiFi, etc), the client needs to connect to the server's actual LAN IP on that network.
If the client and server are connected to different networks (ie, they reach each other over the Internet), the client needs to connect to the public IP of the network that the server is connected to, and that network router will need to have port forwarding configured to route incoming connections to the server device.
Also, note that making the server listen on localhost does not guarantee it will be able to accept clients from other devices, depending on how localhost is implemented. It might resolve to 127.0.0.1 only. The server should instead listen on the wildcard IP 0.0.0.0 so it listens on all available network interfaces that are installed on that device. Or, it can alternatively listen on just the specific LAN IP that will actually be receiving the client connections.
To echo what Remy just correctly said, "connection refused" is really a bit misleading. It basically means that there was no one listening at the address-and-port that the host tried to reach. It does not mean that "there was someone there, but he [actively ...] 'refused to' talk with you." "Connection failed" might have been a better term, but, here we are.

How to configure dd-wrt router, for internet connection from other router in other subnet?

I can not solve this problem.
There modem / router (192.168.1.1) with wifi which distributes online. There wifi and router with dd-wrt, which must also distribute the Internet, but in the subnet 192.168.2.1.
How to configure a router with dd-wrt, that it was possible to connect by cable to the lan port of the first router (192.168.1.1) and when connected to the router on which the dd-wrt on lan or wifi, the device receives from the network ip 192.168.2.X and have access to the internet?
All you should have to do is change the router's LAN address to 192.168.2.1 and adjust the DHCP range and similar parameters to match. All other parameters (other than configuring things you specifically need) can stay at their defaults. Then connect the new router's WAN port to one of the modem/router's LAN ports.

Connect from specific ip address in linux

I'm writing a distributed system and I want to test it on my machine. I created several ip addresses on the interface lo using ip addr add ip_add dev lo.
I have binded all servers to their specific addresses and now I want my servers to connect to each other such that each server would think that it connects from his own ip. But when I use connect I get connection from my localhost. How is it possible to connect from a specific ip address?
It turned out that calling bind() on my socket does all necessary work.

Node server fails to listen to public IP

I am trying to get my Node.js server to listen to a public IP so that I can access it on a different network than my home network.
I've purchased a domain and used a DNS host - right now I'm using No-IP and have downloaded their client to push my IP to their servers.
When I set the IP on No-IP configuration to my local IP I can use the domain name and hit my server on another computer on my network. But if I change this to my public IP and use the domain, the request hangs for about 10 seconds and then fails. I've set up port forwarding (I believe correctly) and opened inbound / outbound traffic on the port I'm listening to (not 80 right now). I even pulled my firewall completely.
I tried changing server.listen(4444) to server.listen(4444, '0.0.0.0') as I've seen all over the web. But this doesn't work.
Anyone have ideas out there? I feel like maybe my ISP is blocking it somehow? I'm fairly new to networking, so maybe I'm missing something critical?
Thanks!
server.listen(4444) should be fine. As long as you don't have multiple active network connections in your server, you don't need to specify an IP address. Port forwarding from your router (if configured correctly) will direct the request that came from to public IP address to the actual local IP address of your host.
Note that for port forwarding to work reliably, you will have to give your host a fixed private IP address (not a DHCP assigned address) so the IP address will not vary. Then, you configure port forwarding to that fixed IP address.
Then, you need to do some network debugging. From a computer outside your own network (e.g. something out on the internet), you should do a couple commands to your public DNS name:
ping yourserver.net
tracert yourserver.net
If your DNS entry is not working, ping should tell you immediately that it didn't find yourserver.net.
If the DNS entry is working, but the IP address can't be reached, then ping will tell you that the server is unreachable. At that point, you will know you have a networking issue with connecting to your public IP address from the internet.
If ping is initially finding your server, but packets aren't flowing properly, then either the ping results or the tracert results should give you an idea where to look next.
If ping and tracert are finding your public IP and packets are flowing to/from it, but you still can't connect to it with the browser, then you either don't have the IP address set correctly (so you're not connecting to the right server) or your node.js server isn't listening appropriately or you aren't using the right ip/port in the browser that represents the actual node.js process. If you suspect this to be the case, then back up and make sure you have everything working purely on your own private network where the browser tries to connect directly to the local IP address and port. When that is working, you will know the node.js server is working appropriately and you can move back to working on the public IP.
FYI, if you tell us what the public DNS name and public IP address is, we here can do a few steps of this debugging from our computers.
It may be that your router can only forward a port to a computer on your network, but not change the port when forwarding. If that's the case, then you have these options:
Put everything on port 4444. Have your server listen to 4444, specify 4444 in the port forwarding in the router and then put 4444 in the URL like http://thecastle.ninja:4444.
Set up the port forwarding for port 80, put your server on port 80. Change the port forwarding to port 80. Change your server to listen to port 80 (if your server is Unix, you will need elevated privileges to listen to port 80 directly). You should then be able to use a URL like http://thecastle.ninja.
Set up the port forwarding for port 80, put your server on port 4444 and use ip table settings to route 80 to 4444 on your server. This allows your server to run in the less privileged 4444 port, but lets the end-user use the default port 80. I have a node.js server on a Linux Raspberry Pi configured this way. You should then be able to use a URL like http://thecastle.ninja
Run a proxy on your server that will route port 80 to port 4444. This is probably more than you need, but nginx is a popular one and it can do port forwarding on the server.

Resources