0

I've recently been tinkering around with the python socket module and I have come across an issue. Here is my python server side script (im using python3.8.2)

import socket
#defin socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 0))
s.listen(5)
while True:
 clientsocket, address = s.accept()
 print(f"connection from client has been established")
 clientsocket.send(bytes("welcome to the server!", "utf-8"))

My server side script runs fine, however when i run the client script

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(127.0.0.1), 0))
msg = s.recv(1024)
print(msg.decode("utf-8")) 

i get the following:

File "client.py", line 3
 s.connect((socket.gethostname(127.0.0.1), 0))
 ^
SyntaxError: invalid syntax

I've tried changing the IP to my computer host name and gives the following:

raceback (most recent call last):
 File "client.py", line 3, in <module>
 s.connect(socket.gethostname((LAPTOP-XXXXXXX), 0))
NameError: name 'LAPTOP' is not defined
YatShan
4432 gold badges8 silver badges22 bronze badges
asked Feb 19, 2020 at 4:50

3 Answers 3

1

There are multiple issues:

  • when specifying IP addresses and hostnames, they must be formatted as strings (e.g. "127.0.0.1" and "LAPTOP-XXXXXXX"). Specifying them without quotes causes Python to attempt to interpret them as other tokens, such as variable names, reserved keyword, numbers, etc., which fails causing erros such as SyntaxError and NameError.
  • socket.gethostname() does not take an argument
  • specifying port 0 in the socket.bind() call results in a random high numbered port being assigned, so you either need to hardcode the port you use or dynamically specify the correct port in your client (e.g. by specifying it as an argument when executing the program)
  • in the server code, socket.gethostname() may not end up using the loopback address. One option here is using an empty string, which results in accepting connections on any IPv4 address.

Here's a working implementation:

server.py

import socket
HOST = ''
PORT = 45555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
host_addr = s.getsockname()
print("listening on {}:{}".format(host_addr[0], host_addr[1]))
s.listen(5)
while True:
 client_socket, client_addr = s.accept()
 print("connection from {}:{} established".format(client_addr[0], client_addr[1]))
 client_socket.send(bytes("welcome to the server!", "utf-8"))

client.py

import socket
HOST = '127.0.0.1'
PORT = 45555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
msg = s.recv(1024)
print(msg.decode("utf-8"))

Output from the server:

$ python3 server.py
listening on 0.0.0.0:45555
connection from 127.0.0.1:51188 established
connection from 127.0.0.1:51244 established

Output from client:

$ python3 client.py
welcome to the server!
$ python3 client.py
welcome to the server!
answered Feb 19, 2020 at 5:19
Sign up to request clarification or add additional context in comments.

2 Comments

thank you for your help! After reading your code i have a better understanding of it but i am confused with the following lines: print({}:{}".format(host_addr[0], host_addr[1])). im thinking maybe the {}:{} is specifying the ip and port somehow but im unsure about the host_addr[0] and host_addr[1] as to what they refer too in the code
socket.getsockname() returns a (host, port) tuple in the AF_INET (IPv4) context. So host_addr[0] and host_addr[1] refer to the first and second elements of that tuple. In regards to the instances of {} within the string, those are placeholders that are replaced by the arguments passed to str.format() method.
0

Put the 127.0.0.1 as string in gethostname

Comments

0

In the /etc/hosts file content, You will have an IP address mapping with '127.0.1.1' to your hostname. This will cause the name resolution to get 127.0.1.1. Just comment this line. So Every one in your LAN can receive the data when they connect with your ip (192.168.1.*). Used threading to manage multiple Clients.

Here's the Server and Client Code: Server Code:

import socket
import os
from threading import Thread
import threading
import time
import datetime
def listener(client, address):
 print ("Accepted connection from: ", address)
 with clients_lock:
 clients.add(client)
 try: 
 while True: 
 client.send(a)
 time.sleep(2) 
 finally:
 with clients_lock:
 clients.remove(client)
 client.close()
clients = set()
clients_lock = threading.Lock()
host = socket.getfqdn() # it gets ip of lan
port = 10016
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(3)
th = []
print ("Server is listening for connections...")
while True:
 client, address = s.accept()
 timestamp = datetime.datetime.now().strftime("%b %d %Y,%a, %I:%M:%S %p")
 a = ("Hi Steven!!!" + timestamp).encode()
 th.append(Thread(target=listener, args = (client,address)).start())
s.close()

Client Code:

import socket
import os
import time
s = socket.socket() 
host = '192.168.1.43' #my server ip 
port = 10016
print(host)
print(port)
s.connect((host, port))
while True:
 print((s.recv(1024)).decode())
s.close() 

Output:

(base) paulsteven@smackcoders:~$ python server.py 
Server is listening for connections...
Accepted connection from: ('192.168.1.43', 38716)
(base) paulsteven@smackcoders:~$ python client.py 
192.168.1.43
10016
Hi Steven!!!Feb 19 2020,Wed, 11:13:17 AM
Hi Steven!!!Feb 19 2020,Wed, 11:13:17 AM
Hi Steven!!!Feb 19 2020,Wed, 11:13:17 AM
answered Feb 19, 2020 at 5:45

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.