如何在Python中从同一个套接字发送和接收?

时间:2015-11-27 16:11:00

标签: python sockets

我正在尝试用Python编写一个可以从同一个套接字发送和接收的客户端程序,但是它总是给我一个错误,哪个地址已经被使用了。这是我试图写的功能。

def Login():
    username=raw_input()
    password=raw_input()
    message=raw_input()
    array=[username,password,message]

    TCP_IP = '127.0.0.1'
    TCP_PORT = 5563
    BUFFER_SIZE = 1024  # Normally 1024, but we want fast response
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((TCP_IP, TCP_PORT))
    array_string=pickle.dumps(array)
    sock.send(array_string)
    sock.close()

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((TCP_IP, TCP_PORT))
    sock.listen(1)

    conn, info = sock.accept()
    while 1:
        data = serverSocket.recv(1024)
        if not data:break
    conn.send(data)  
    conn.close()

2 个答案:

答案 0 :(得分:0)

这里有一堆真正的新手错误。

  1. 您无法将TCP套接字连接到自身。应该有两个不同的插座。

  2. 如果您真的想要获取先前在侦听套接字上发送的数据,则应创建,绑定和配置此侦听套接字,以便在客户端连接之前监听(或者,至少,与此连接尝试并行,在几秒钟内,所以连接尝试将尝试 - 但这很可能不会在localhost上工作。)

  3. 如果两者都阻塞,你就不能在同一个线程中等待连接和接受。最简单的方法是将客户端和服务器端分成2个不同的程序并手动并行运行。然后,在成功调试之后,您将能够在同一进程的不同线程中执行此操作,或使用事件驱动的引擎。

答案 1 :(得分:0)

虽然您可能无法将套接字连接到自身以发送和接收数据,但您可以从以下示例中学习,这些示例的灵感来自于尝试执行类似操作的代码。

import _thread
import pickle
import socket
import time


def main():
    """Run a server in a thread and start a client to talk to it."""
    _thread.start_new_thread(run_server, ('', 5563))
    run_client('localhost', 5563)


def run_server(host, port):
    """Handle all incoming connections by spawning worker threads."""
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((host, port))
    server.listen(5)
    while True:
        _thread.start_new_thread(handle_connection, server.accept())


def handle_connection(client, address):
    """Answer an incoming question from the connected client."""
    print('Incoming connection from', address)
    client.settimeout(0.1)
    data = recvall(client)
    client.shutdown(socket.SHUT_RD)
    question = pickle.loads(data)
    answer = '''len(username) = {}
len(password) = {}
len(message) = {}'''.format(*map(len, question))
    client.sendall(answer.encode())
    client.shutdown(socket.SHUT_WR)
    client.close()
    print('Finished with', address)


def recvall(connection):
    """Receive all data from a socket and return as a bytes object."""
    buffer = bytearray()
    while True:
        try:
            data = connection.recv(1 << 12)
        except socket.timeout:
            pass
        else:
            if data:
                buffer.extend(data)
            else:
                return bytes(buffer)


def run_client(host, port):
    """Collect information from question and display returned answer."""
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    time.sleep(0.1) # wait for server to start listening for clients
    client.connect((host, port))
    time.sleep(0.1) # wait for handler thread to display connection
    username = input('Username: ')
    password = input('Password: ')
    message = input('Message: ')
    question = pickle.dumps((username, password, message))
    client.sendall(question)
    client.shutdown(socket.SHUT_WR)
    answer = recvall(client)
    client.shutdown(socket.SHUT_RD)
    client.close()
    print(answer.decode())
    time.sleep(0.1) # wait for handler to cleanly terminate execution

if __name__ == '__main__':
    main()