通过套接字发送字符串(python)

Posted

技术标签:

【中文标题】通过套接字发送字符串(python)【英文标题】:Sending string via socket (python) 【发布时间】:2014-02-09 14:00:42 【问题描述】:

我有两个脚本,Server.py 和 Client.py。 我有两个目标:

    能够一次又一次地从客户端向服务器发送数据。 能够将数据从服务器发送到客户端。

这是我的 Server.py :

import socket

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.3"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))

serversocket.listen(5)
print ('server started and listening')
while 1:
    (clientsocket, address) = serversocket.accept()
    print ("connection found!")
    data = clientsocket.recv(1024).decode()
    print (data)
    r='REceieve'
    clientsocket.send(r.encode())

这是我的客户:

#! /usr/bin/python3

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host ="192.168.1.3"
port =8000
s.connect((host,port))

def ts(str):
   s.send('e'.encode()) 
   data = ''
   data = s.recv(1024).decode()
   print (data)

while 2:
   r = input('enter')
   ts(s)

s.close ()

该功能第一次工作('e' 进入服务器,我得到返回消息),但我如何让它一遍又一遍地发生(类似于聊天应用程序)? 问题在第一次之后开始。消息不会在第一次之后发送。 我究竟做错了什么? 我是python新手,所以请稍微详细一点,如果可以的话,请给出整个东西的源代码。

【问题讨论】:

【参考方案1】:
import socket
from threading import *

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.3"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))

class client(Thread):
    def __init__(self, socket, address):
        Thread.__init__(self)
        self.sock = socket
        self.addr = address
        self.start()

    def run(self):
        while 1:
            print('Client sent:', self.sock.recv(1024).decode())
            self.sock.send(b'Oi you sent something to me')

serversocket.listen(5)
print ('server started and listening')
while 1:
    clientsocket, address = serversocket.accept()
    client(clientsocket, address)

这是一个非常简单的设计,您可以如何解决它。 首先,您需要在进入 while 1 循环之前接受客户端(服务器端),因为在每个循环中您都接受一个新客户端,或者按照我的描述,您将客户端扔到一个单独的线程中从现在开始自己处理。

【讨论】:

正是您所要求的,“类似于聊天应用程序”。这是一个聊天应用程序。您的 serversocket.accept() 接受一个套接字,将其传递到类 client() 这是一个线程。该线程将与您的 accept() 函数一起运行,不会阻止其他人连接,同时仍然做两件事。 1) 从客户端接收数据。 2) 在每条消息中回复客户“Oi you sent something to me”。 @user2670775 另外,您可以使用您已经拥有的 client.py,我“编写”的这个 server.py 也可以与您的客户端代码一起使用。 错误:线程 Thread-1 中的异常:回溯(最后一次调用):文件“C:\Python33\lib\threading.py”,第 901 行,在 _bootstrap_inner self.run() 文件中“C:\Users\Harsh's\Desktop\New 文件夹 (2)\Sserver.py”,第 20 行,运行中 print('Client sent:', self.sock.recv(1024).decode()) ConnectionAbortedError: [ WinError 10053] 已建立的连接已被主机中的软件中止 你断开了客户端? 让我们continue this discussion in chat【参考方案2】:

客户端.py

import socket

s = socket.socket()
s.connect(('127.0.0.1',12345))
while True:
    str = raw_input("S: ")
    s.send(str.encode());
    if(str == "Bye" or str == "bye"):
        break
    print "N:",s.recv(1024).decode()
s.close()

server.py

import socket

s = socket.socket()
port = 12345
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print "Socket Up and running with a connection from",addr
while True:
    rcvdData = c.recv(1024).decode()
    print "S:",rcvdData
    sendData = raw_input("N: ")
    c.send(sendData.encode())
    if(sendData == "Bye" or sendData == "bye"):
        break
c.close()

这应该是您想要的聊天应用程序的小型原型的代码。 在单独的终端中运行它们,然后只检查端口。

【讨论】:

【参考方案3】:

这段代码不正确。

while 1:
    (clientsocket, address) = serversocket.accept()
    print ("connection found!")
    data = clientsocket.recv(1024).decode()
    print (data)
    r='REceieve'
    clientsocket.send(r.encode())

serversocket 上的accept() 的调用会阻塞,直到有客户端连接。当您第一次从客户端连接到服务器时,它会接受连接并接收数据。但是,当它再次进入循环时,它正在等待另一个连接并因此阻塞,因为没有其他客户端正在尝试连接。

这就是recv 只能在第一次正确工作的原因。您应该做的是找出如何处理与已接受的客户端的通信 - 也许通过创建一个新线程来处理与该客户端的通信并继续在循环中接受新客户端,以相同的方式处理它们。

提示:如果你想创建自己的聊天应用程序,你应该看看像 Twisted 这样的网络引擎。它也将帮助您更好地理解整个概念。

【讨论】:

那我应该怎么修改呢?我必须修改客户端和服务器吗? 在您编写的while循环中,只接受新客户端的连接。您通常必须使其成为多线程,然后才能从客户端读取数据并将数据发送回。 我并没有真正制作聊天应用程序。我想从我的树莓派接收和发送数据。好吧,假设我只想要一种方式传输到服务器,那我该怎么办? 如果您只是在寻找单向通信,您可以在服务器中编写一个 Thread 类来为该客户端处理它。线程将永远从客户端接收数据。因此,通过这种设计,您将为每个客户端连接生成一个新线程,并要求服务器在该线程中处理与该特定客户端相关的所有通信。 如果你只想处理单向通信,你只需要修改服务器

以上是关于通过套接字发送字符串(python)的主要内容,如果未能解决你的问题,请参考以下文章

C++ 通过套接字发送字符串

通过Java中的套接字发送字符串而不是字节

通过套接字以字符串形式发送数据的好方法是啥?

C ++单个字符未通过套接字发送

通过 ZeroMQ 以字符串形式接收对象然后通过另一个套接字以零副本发送它的正确方法是啥?

Python网络编程利用Python进行TCPUDP套接字编程