python - Python - 如何通过 socket.makefile 执行套接字通信?
问题描述
基于对这篇文章的最高评价:
和码头:
https://docs.python.org/3/library/socket.html#targetText=socket.makefile
我正在尝试弄清楚如何使用socket.makefile
通过套接字发送/接收。这是我到目前为止所拥有的:
服务器.py:
# Server.py
import socket
# module-level variables
HOST='127.0.0.1'
PORT=65439
ACK_TEXT = 'text_received'
def main():
# instantiate a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket instantiated')
# bind the socket
sock.bind((HOST, PORT))
print('socket binded')
# start the socket listening
sock.listen(10)
print('socket now listening')
# accept the socket response from the client, get the connection object
conn, addr = sock.accept() # Note: execution waits here until the client calls sock.connect()
print('socket accepted, got connection object')
sockFile = sock.makefile()
while True:
message = sockFile.readline()
print('received: ' + str(message))
# end while
# end main
if __name__ == '__main__':
main()
客户端.py:
# Client.py
import socket
import time
# module-level variables
HOST='127.0.0.1'
PORT=65439
ACK_TEXT = 'text_received'
def main():
# instantiate a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket instantiated')
# connect the socket
sock.connect((HOST, PORT)) # Note: if execution gets here before the server starts up, this line will cause a crash
print('socket connected')
sockFile = sock.makefile(mode='w')
myCounter = 0
while True:
message = 'message ' + str(myCounter)
print('sending: ' + message)
sockFile.write(message)
myCounter += 1
time.sleep(1) # wait for 1 sec before sending next text message
# end while
# end main
if __name__ == '__main__':
main()
现在,如果我启动服务器,然后从单独的命令提示符启动客户端,客户端似乎正在工作:
客户端.py 输出:
$ python3 Client.py
socket instantiated
socket connected
sending: message 0
sending: message 1
sending: message 2
sending: message 3
sending: message 4
sending: message 5
但服务器因错误而失败:
$ python3 Server.py
socket instantiated
socket binded
socket now listening
socket accepted, got connection object
Traceback (most recent call last):
File "Server.py", line 38, in <module>
main()
File "Server.py", line 32, in main
message = sockFile.readline()
File "/usr/lib/python3.6/socket.py", line 586, in readinto
return self._sock.recv_into(b)
OSError: [Errno 107] Transport endpoint is not connected
使用时如何在服务器上成功连接传输端点socket.makefile
?我不确定在这种情况下的语法是什么。我最终没有使用conn
,addr
就像我在服务器上使用更传统的方式一样,也许这就是我出错的地方?
- - 编辑 - -
在Server.py
我尝试使用connection
withmakefile()
函数时,如下所示:
.
.
.
# accept the socket response from the client, get the connection object
conn, addr = sock.accept() # Note: execution waits here until the client calls sock.connect()
print('socket accepted, got connection object')
connFile = conn.makefile()
while True:
message = connFile.readline()
print('received: ' + str(message))
# end while
.
.
.
但这也不起作用,Client.py
仍然像以前一样工作,但现在Server.py
只是挂起:
$ python3 Server.py
socket instantiated
socket binded
socket now listening
socket accepted, got connection object
(hangs here forever)
--- 编辑2 ---
现在我真的很困惑。基于这篇文章:
https://bugs.python.org/issue35928
我几乎复制了海报代码,所以 Server.py 现在看起来像这样:
# Server.py
import socket
# module-level variables
HOST='127.0.0.1'
PORT=65439
ACK_TEXT = 'text_received'
def main():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
print(f'Waiting for connection on port {s.getsockname()[1]}')
s.listen(1)
conn, addr = s.accept()
print(f'Connected by {addr}')
with conn:
f = conn.makefile(mode='rw')
while True:
print('before f.readline()')
m = f.readline()
print('after f.readline()')
print(f'msg: {m!r}')
if not m:
exit(0)
f.write(m)
f.flush()
# end main
if __name__ == '__main__':
main()
并且Server.py
仍然挂在阅读上!!
$ python3 Server.py
Waiting for connection on port 65439
Connected by ('127.0.0.1', 47536)
before f.readline()
根据回复中的最后一篇文章,据说发帖人最初的担忧已经得到解决,因此现在应该可以使用了。我仍然不确定如何做到这一点。
--- 编辑3 ---
我正在使用Ubuntu 18.04.3
最新的更新,Python 3.6.9
如果这很重要
解决方案
在您的服务器代码中:
conn, addr = sock.accept()
calls sock.connect()
sockFile = sock.makefile()
while True:
message = sockFile.readline()
您制作了一个客户端套接字(conn),但您从未使用过它。客户端正在写入,因此您应该从客户端套接字(conn)读取另外我认为您应该从while循环内部调用accept。
while True:
conn, addr = sock.accept()
sockFile = conn.makefile()
message = sockFile.readline()
推荐阅读
- azure-sql-database - 是否有基于 UI 的方式将 csv 数据加载到 Azure SQL 数据库?
- python - 为什么我不能更改当前工作目录?
- javascript - mediaElement.play() 方法返回一个被拒绝的承诺
- lua - LuaJIT FFI 将 char** 传递给 C 函数
- timber - Timber\ImageHelper 裁剪在特定服务器上不起作用
- powershell - 在工作流中包含 PowerShell 工作流脚本
- r - 根据两组计算行之间的差异
- reactjs - 仅在输入有效时提交 onBlur 函数
- prestashop - Prestashop 1.6 根本不加载
- wso2 - URL 中的 WSO2 非英文字符