Создание исходящего соединения - PullRequest
0 голосов
/ 19 февраля 2020

Недавно я возился с модулем сокета python и столкнулся с проблемой. Вот мой python серверный скрипт (я использую 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"))

Мой серверный скрипт работает нормально, однако когда я запускаю клиентский скрипт

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")) 

я получаю следующее:

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

Я попытался сменить IP на имя хоста моего компьютера и выдает следующее:

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

Ответы [ 3 ]

0 голосов
/ 19 февраля 2020

Существует несколько проблем:

  • при указании IP-адресов и имен хостов они должны быть отформатированы как строки (например, "127.0.0.1" и "LAPTOP-XXXXXXX"). При указании их без кавычек Python пытается интерпретировать их как другие токены, такие как имена переменных, зарезервированное ключевое слово, числа и т. Д. c., Что приводит к ошибкам, таким как SyntaxError и NameError.
  • socket.gethostname() не принимает аргумент
  • указание порта 0 в вызове socket.bind() приводит к назначению случайного порта с высоким номером, поэтому вам нужно либо жестко кодировать используемый порт, либо динамически укажите правильный порт в вашем клиенте (например, указав его в качестве аргумента при выполнении программы)
  • в коде сервера, socket.gethostname() может не в конечном итоге использовать адрес обратной связи. Один из вариантов здесь - использование пустой строки, что приводит к принятию соединений на любом IPv4-адресе .

Вот рабочая реализация:

сервер. 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"))

Вывод с сервера:

$ 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

Вывод с клиента:

$ python3 client.py
welcome to the server!
$ python3 client.py
welcome to the server!
0 голосов
/ 19 февраля 2020

В содержимом файла /etc/hosts у вас будет IP-адрес, сопоставленный с '127.0.1.1' вашему имени хоста. Это заставит разрешение имени получить 127.0.1.1. Просто прокомментируйте эту строку. Таким образом, каждый в вашей локальной сети может получать данные при подключении к вашему ip (192.168.1. *). Используется threading для управления несколькими клиентами.

Вот код сервера и клиента: Код сервера:

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()

Код клиента:

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() 

Вывод:

(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
0 голосов
/ 19 февраля 2020

Поместите 127.0.0.1 как строку в gethostname

...