Python 3 localhost connection - python

I'm trying to run the below program but I keep getting connection error's:
from socket import *
from codecs import decode
HOST = 'localhost'
PORT = 5000
BUFSIZE = 1024
ADDRESS = (HOST, PORT)
server = socket(AF_INET, SOCK_STREAM)
server.connect(ADDRESS)
dayAndTime = decode(server.recv(BUFSIZE), 'ascii')
print(dayAndTime)
server.close()
ERROR: ConnectionRefusedError: [Errno 61] Connection refused
Any idea what's going on?

If your book doesn't mention the other half of sockets, you need a better book.
Socket basics are easy. You have one process listen on a port, waiting for connections. Commonly we'll call this a 'server'. Another process (perhaps on the same machine, perhaps remote) attempts to connect to that port. We'll call that the client.
If no one is listening, then when the client attempts to connect they'll get your error Connection Refused.
So, set up a listening process. Below, on the left is server code; on the right is client code. Top-to-bottom is the "flow".
server = socket(AF_INET, SOCK_STREAM) # <- just like your example
server.bind(ADDRESS) # rather than 'connect', we 'bind' to the port
server.listen(1) # bind "claims" the port, so next we call listen & wait...
# Meanwhile...
# Your client process
client = socket(AF_INET, SOCK_STREAM)
client.connect(ADDRESS)
# It's only at this moment that the client reaches across the network to the server...
# On connect, the listening server wakes up, and needs to "accept" the connection
(s, remote_addr) = server.accept()
Once accepted, you can now send/recv on the s socket on the server-side, and send/recv from the client socket on the client side. Note that the server variable is not the socket to communicate on -- it's used to listen for new connections. Instead, you read/write on the socket object returned as first item of accept().
There's lots more to consider but this is at the heart of the Internet and has been pretty much unchanged since the 1980s.
Image from wikipedia entry for Berkeley Sockets:

Related

Peer to peer socket communication without port forwarding

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.

Can I make a client socket only to establish a connection using python 3.6

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.

how to avoid two socket with same port number python

Now here is sample for the server part of socket.
I want to have serverSocket and connectionSocket with different port number, but for now, they are using same port number.
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET,SOCK_STREAM)
serverSocket.bind((‘’,serverPort))
serverSocket.listen(1)
print (‘The server is ready to receive’)
while 1:
connectionSocket, addr = serverSocket.accept()
sentence = connectionSocket.recv(1024)
capitalizedSentence = sentence.upper()
connectionSocket.send(capitalizedSentence)
connectionSocket.close()
if they are using same port number, would there be some collision?
There is nothing to avoid, and there is really no easy way to avoid it - this is how TCP is supposed to work.
In TCP there are 2 kinds of sockets:
listening server sockets
connected sockets
The server sockets start listening to incoming connections with listen; and wait for client connections with accept. Clients create a socket that is connected to the server address (host, port). When the server accepts a connection, a new connected socket is created between the (client_address, client_port) and (server_address, server_port). The TCP stack on the server can see from status bits easily if the packet is a connection request, or destined to an already connected socket. If it is a communication between already connected sockets, then it finds out the file descriptor that is bound on the local address and local port and is connected with the source address, source port of the remote end.
The connected socket will have the same port as the listening server socket; both Ende of the socket know 4 things: local address, local port, remote address and remote port. You can have 1 server socket bound on 10.20.30.40:12345 at the same time with thousands of sockets connected from 10.20.30.40:12345 to thousands distinct addresses.
There is really congestion only in the connection attempt phase; the server_socket.listen(1) means that the server will queue just 1 incoming connection; subsequent connections will be rejected until the incoming connection is accepted.
From Linux manual pages, listen(2) on the backlog argument of sock.listen:
The backlog argument defines the maximum length to which the
queue of pending connections for sockfd may grow. If a connection request arrives when the queue is full, the client may
receive an error with an indication of ECONNREFUSED or, if the
underlying protocol supports retransmission, the request may be
ignored so that a later reattempt at connection succeeds.
Althouh I've never used raw sockets in Python, I guess this question more generally deals with how TCP and IP work.
When a server listens for connections on a port, clients will connect to that port, and the TCP connection can be identified by the quadruple (server_addr, server_port, client_addr, client_port), so there is no ambiguity when packets belonging to different connections will be sent or recieved, because the (client_addr, client_port) part will be different for each of them.
That said, there is no conflict in the addressing.
However, note that it is common that servers fork (or spawn a thread) after accepting each request, so that the main proces (or thread) can keep acceprint connections while other connections are handled by the forked processes (or threads). In your case, instead, once your server starts processing a request, it computes the response before calling accept() again, so any other client will have to wait before having its request served.

Selecting random port on a remote host

I want to select a random high port on a remote linux machine and use it for my application. On my localhost, I can bind to port 0 and get a random high port, but this does not work if I give a remote host.
The code is as follows:
host = "remote_host"
def get_open_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,0))
s.listen(1)
port = s.getsockname()[1]
s.close()
return port
Error:
Traceback (most recent call last):
File "server.py", line 25, in <module>
port = get_open_port()
File "server.py", line 11, in get_open_port
s.bind((host,0))
File "<string>", line 1, in bind
Well I guess you are bit confused with the client-server communication. Before getting to the solution of your problem lets first revisit the client-server communication process. Normally it is the client who makes/initiates the connection request (simply a connection) to the server. The client makes a request to the server on a remote port which is listening for incoming connections. This remote port should be open on the server side and should be waiting for incoming connections. For eg: If you want to connect to a remote server on the remote port number 15200, then it is mandatory that you should open the port number 15200 on the server side and it should be listening for any incoming connections/requests. Also, the client will know this in advance to which remote port it should make a request for a connection!
Lets understand some more facts before getting to the one of the possible solution to your problem. First lets understand the server side.
Server side: You are trying the server to use any random port for accepting incoming connections from a client. It will surely work as you are binding port number 0 in your server code as s.bind((host,0)). When you bind the port number 0 then your server (actually the OS which is running the server script) will use any random high port number for accepting the remote connections which will be usually greater than 1023. You can test this by following code snippet. Run the following code snippet and you may notice that the server is opening random high port numbers.
import socket
host = "127.0.0.1"
def get_open_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,0))
s.listen(1)
port = s.getsockname()[1]
s.close()
return port
for i in range(0,5):
print "Opening port no. %s"%get_open_port()
On executing the above code you'll shall see that a random port number is being selected by the server code to accept incoming connections every time. But it is also closing it after wards using s.close(). In my case the output was as below (You may get a different set of port numbers):
Opening port no. 60876
Opening port no. 60877
Opening port no. 60878
Opening port no. 60879
Opening port no. 60880
So, I guess now you understood the server part. Lets discuss the client side now.
Client side: As mentioned earlier that a client needs to know the remote server port to which it needs to connect. A typical client code looks as given below:
import socket
host = "127.0.0.1"
port = 60880
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
In the above code snippet this line s.connect((host, port)) you need to mention the host the remote host name or IP and port the remote port to which you want to connect to.
So it means that client should know the port number in advance! As a result you have to mention the port in your client code. As I have done in my code snippet as port = 60880.
Now coming to your question: As you already noticed from above text that you have to mention the remote server's port number in client code to make a request for a connection. So, you can't expect your client to figure out itself the remote port of the server which is actually listening for incoming request. The client code can't do this by its own.
Solution:
So what if the client code can't figure out by itself the remote port number we'll make it to figure it out! ;) What we know is if you bind the port number 0 on server side then a random port number will be selected which will be greater than 1023. So, it means the random port number will always be greater than 1023. Also, the maximum value of port number is 65535. Ultimately we come to a conclusion that the random port that will used by the server will be any port number in this range 1024 - 65335.
Now all you have to do is in your client code you have to use a range of port numbers to which it should make connection. Because we don't know what remote port is listening on the server side for accepting incoming requests/connection!
Sample code for plying around: I tested these code snippets using my localhost. Here is the server code. Run the server code first then run the client code. Upon executing the server code, it'll display in console/output that what is the random port number opened for accepting incoming request/connections. When a client is connected the server will display a message the Got a client connected along with the IP of the client.
#This is the server script
import socket
host = "127.0.0.1"
def get_open_port():
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mySocket.bind((host,0))
mySocket.listen(1)
port = mySocket.getsockname()[1]
print "Port opened for incoming connections %d"%port
(clientSocket, clientAddress) = mySocket.accept()
print "Got a client: ", clientAddress
clientSocket.close()
mySocket.close()
get_open_port()
Here is a client code sample that will do this crazy stuff. It will try to connect on all the ports from 1024 - 65335 and when it finds any remote port which is listening for incoming connections. It will display a message "Connected to remote port" and then close the socket and continue looking for more open ports until it reaches the last port number 65355.
#This is the client script
import socket
host = "127.0.0.1"
def startConn():
for port in range(1024,65336):
try:
myClientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Trying remote port: ",port
myClientSocket.connect((host,port))
print "Connected to remote port: ",port
myClientSocket.close()
except socket.error as msg:
myClientSocket.close()
continue
startConn()
This is just a sample code, I am intentionally closing the sockets after a successful is established. You can do something else what you ever you prefer. I hope now it is quite clear to you regarding server-client communication.

What is this address that I'm getting from recvfrom?

I am trying to learn about network communications and sockets. Here is some code that I wrote:
Client code:
from socket import *
sock = socket(AF_INET, SOCK_DGRAM)
sock.bind('127.0.0.1', 3000)
data, addr = sock.recvfrom(1024)
print "Received data '" + data + "' from address:", addr
Server code:
from socket import *
sock = socket(AF_INET, SOCK_DGRAM)
sock.sendto("HELLO WORLD", ('127.0.0.1', 3000))
sock.close()
The client prints out: Received data 'HELLO WORLD!' from address: ('127.0.0.1', 60788)
To my understanding, the second member of the tuple is supposed to be the port. Furthermore, if I send several messages the number increase by 1 every time. Why is it not 3000?
As a side-note, are the htons and htonl functions necessary with the python API?
First of all: The scripts that you've written here would typically be regarded as a server and client, respectively, not client and server. This is because the server (the first script) is binding to a known port and waiting for a connection, while the client (the second script) is connecting to it from a random port and sending data.
To answer your questions directly:
Since you aren't binding the client to any specific port, it's choosing a new epheremal port for each socket, and those are being used sequentially. If the server were to send a packet back to that same host and port, it would be received by the client.
The htons and htonl functions are not generally necessary in Python. The socket module takes care of endian-swapping addresses and port numbers for you.
The port you are seeing is the port the data was sent from, not the port the data was sent to. When you don't specify the source port, and your "server" doesn't, the system assigns the socket a source port.

Categories

Resources