使用 python 套接字发送/接收数据

Posted

技术标签:

【中文标题】使用 python 套接字发送/接收数据【英文标题】:Send/receive data with python socket 【发布时间】:2017-07-13 21:39:24 【问题描述】:

我有一个 ***(使用 Open***),有多个客户端连接到服务器(在 DigitalOcean)。连接非常好,当它们通过 ssh 连接到各自的路由器时,我可以访问放置在各自防火墙后面的每个客户端。我想使用 python 脚本自动将文件从多个客户端发送到服务器,反之亦然。这是我目前使用的代码:

服务器:

#!/usr/bin/env python

import socket
from threading import Thread
from SocketServer import ThreadingMixIn

class ClientThread(Thread):

    def __init__(self,ip,port):
        Thread.__init__(self)
        self.ip = ip
        self.port = port
        print "[+] New thread started for "+ip+":"+str(port)


    def run(self):
        while True:
            data = conn.recv(2048)
            if not data: break
            print "received data:", data
            conn.send(data)  # echo

TCP_IP = '0.0.0.0'
TCP_PORT = 62
BUFFER_SIZE = 1024  # Normally 1024


tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((TCP_IP, TCP_PORT))
threads = []

while True:
    tcpsock.listen(4)
    print "Waiting for incoming connections..."
    (conn, (ip,port)) = tcpsock.accept()
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)

for t in threads:
    t.join()

客户:

#!/usr/bin/env python

import socket


TCP_IP = '10.8.0.1'
TCP_PORT = 62

BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()

print "received data:", data

问题是我无法获得连接。服务器只打印“等待传入连接...”,客户端似乎没有找到通往服务器的路。有没有人可以看看这个并给我一些关于我做错了什么的反馈?

【问题讨论】:

【参考方案1】:

你能试试这样的吗?

import socket
from threading import Thread


class ClientThread(Thread):

    def __init__(self,ip,port):
    Thread.__init__(self)
    self.ip = ip
    self.port = port
    print "[+] New thread started for "+ip+":"+str(port)


def run(self):
    while True:
        data = conn.recv(2048)
        if not data: break
        print "received data:", data
        conn.send(b"<Server> Got your data. Send some more\n")

TCP_IP = '0.0.0.0'
TCP_PORT = 62
BUFFER_SIZE = 1024  # Normally 1024
threads = []

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(("0.0.0.0", 5000))
server_socket.listen(10)

read_sockets, write_sockets, error_sockets = select.select([server_socket], [], [])

while True:
    print "Waiting for incoming connections..."
    for sock in read_sockets:
        (conn, (ip,port)) = server_socket.accept()
        newthread = ClientThread(ip,port)
        newthread.start()
        threads.append(newthread)

for t in threads:
    t.join()

现在客户端将有如下内容:

import socket, select, sys

TCP_IP = '0.0.0.0'
TCP_PORT = 62

BUFFER_SIZE = 1024
MESSAGE = "Hello, Server. Are you ready?\n"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, 5000))
s.send(MESSAGE)
socket_list = [sys.stdin, s]

while 1:
    read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [])


    for sock in read_sockets:
        # incoming message from remote server
        if sock == s:
            data = sock.recv(4096)
            if not data:
                print('\nDisconnected from server')
                sys.exit()
            else:
                sys.stdout.write("\n")
                message = data.decode()
                sys.stdout.write(message)
                sys.stdout.write('<Me> ')
                sys.stdout.flush()

        else:
            msg = sys.stdin.readline()
            s.send(bytes(msg))
            sys.stdout.write('<Me> ')
            sys.stdout.flush()

输出如下:

对于服务器 -

Waiting for incoming connections...
[+] New thread started for 127.0.0.1:52661
received data: Hello, World!
Waiting for incoming connections...

received data: Hi!

received data: How are you?

对于客户-

<Server> Got your data. Send some more
<Me> Hi!
<Me> 
<Server> Got your data. Send some more
<Me> How are you?
<Me> 
<Server> Got your data. Send me more
<Me>

如果您想在客户端和服务器之间建立开放连接,只需在无限循环中保持客户端打开,您也可以在服务器端进行一些消息处理。如果您需要,我可以相应地编辑答案。希望这会有所帮助。

【讨论】:

感谢您的回答!我试图运行您的代码,但连接被拒绝。客户端的输出是: Traceback(最近一次调用最后一次):文件“client_test.py”,第 10 行,在 s.connect((TCP_IP, 5000)) 文件“/usr/lib/python2.7/socket. py",第 224 行,在方法中返回 getattr(self._sock,name)(*args) socket.error: [Errno 111] Connection denied 先运行服务器,后运行客户端。因为没有服务器运行,客户端不知道连接到哪里。 我先运行了服务器,但它给出了相同的输出:连接被拒绝。会不会是防火墙问题?我可以 ping 服务器本地 ip:10.8.0.1 和公共 ip。但我无法使用任何一个 ip 远程登录服务器.. 当我配置 open*** 网络时,我使用了端口 443,并且能够在端口 443 上远程登录:telnet 10.8.0.1 443。如果我使用端口 443 运行客户端代码,我也会得到空白响应,但我无法使用该端口运行服务器代码,因为该端口已在使用中。这应该告诉我什么吗? 端口应该是开放的,以便客户端连接。我不确定您面临的问题是什么。打开服务器将在其上运行的端口,并要求客户端在同一端口上连接到服务器。

以上是关于使用 python 套接字发送/接收数据的主要内容,如果未能解决你的问题,请参考以下文章

Python套接字客户端:发送数据和接收结果

Python 3套接字客户端发送数据和C++套接字服务器接收偏移数据?

python套接字接收二进制数据

Python套接字发送/接收逐渐变慢

如何使用 Python 从 Web 套接字接收数据

XMLSocket 可以接收数据但不能发送