下面是代码, server 端会在 recv 上挂住 这个是为什么?
server:
# -*- coding: UTF-8 -*-
# 导入库
import socket, threading, os, uuid, sys
SIZE = 1024 * 1024 * 5
filename = str(uuid.uuid4()) + '.jpg'
# 检查当前目录下是否有等下要命名的图片,有的话删除之
def checkFile():
list = os.listdir('.')
for iterm in list:
if iterm == filename:
os.remove(iterm)
print('remove')
else:
pass
# 接受数据线程
def tcplink(sock, addr):
# def tcplink():
print('Accept new connection from %s:%s...' % addr)
# sock.send(b'Welcome from server!')
print('receiving, please wait for a second ...')
while True:
try:
data = sock.recv(SIZE)
if not data :
print('reach the end of file')
break
elif data == 'begin to send':
print('create file')
checkFile()
with open(filename, 'wb') as f:
pass
else:
with open(filename, 'ab') as f:
f.write(data)
except:
print("Unexpected error:", sys.exc_info()[0])
break
print('msg send')
sock.send(b'Welcome from server!')
sock.close()
print('receive finished')
print('Connection from %s:%s closed.' % addr)
# 创建一个 socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口(这里的 ip 要在不同的情况下更改)
s.bind(('127.0.0.1', 9999))
# 每次只允许一个客户端接入
s.listen(2)
print('Waiting for connection...')
while True:
# 建立一个线程用来监听收到的数据
sock, addr = s.accept()
t = threading.Thread(target = tcplink, args = (sock, addr))
# 线程运行
t.start()
client:
# -*- coding: UTF-8 -*-
import socket
SIZE = 1024 * 1024 * 5
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('127.0.0.1', 9999))
# 接收欢迎消息:
with open('./image.png', 'rb') as f:
data = f.read()
s.sendall(data)
print('sended !')
data = s.recv(SIZE)
# print(data)
s.close()
print('connection closed')
在filewrite后面加上了break之后没问题了,
现在的listen(2)改成了(1),
就是有概率出现了远程主机强迫关闭的问题, 这个如何解决?
server 端close的地方只有这里这里, 那client端的recv为什么会在收到信息之前socket的断掉了呢?
print('msg sendall')
sock.sendall(b'Welcome from server!')
sock.close()
1
opengps 2018-02-23 09:36:32 +08:00
可惜我不懂你的语言,回答不规范,我看着问题像是 while True 内部那里,没有启用单独的线程处理啊,这样的话,你服务端没法接收并发消息的
|
2
heimeil 2018-02-23 09:41:14 +08:00
不知道是不是没收到 welcome,你仔细看看 server 在 send welcome 之前就 while True 了
|
3
coderwang 2018-02-23 09:49:21 +08:00
f.write(data) 之后 break
|
4
j0hnj 2018-02-23 09:55:06 +08:00 via iPhone
客户端 sendall 之后就把 socket shutdown 吧,这样服务端的 recv 才会收到 EOF 返回,不然就卡住了。或者也可以像 HTTP 一样加一个 content-length 字段
|
5
j0hnj 2018-02-23 10:18:12 +08:00 via iPhone
具体一下就是客户端在 sendall 之后应该 s.shutdown(socket.SHUT_WR) 关闭自己的写端
|
6
linyinma 2018-02-23 10:23:07 +08:00
这边有几个问题:
( 1 )首先检查./image.png 文件是否存在(文件大小,是否是空文件); ( 2 ) data = sock.recv(SIZE) if not data : print('reach the end of file') 这不是文件发送完的意思,是代表对方关闭了 socket,你不能这样写; ( 3 ) TCP 流你无法确定应用层报文是否发送完整,你需要定义一套应用层协议,比如定义头两个字节表示文件长度,服务端先读两个字节判断应用层报文大小,然后读完整个报文~~ |
7
woshichuanqilz OP @coderwang 你好 确实是 break 哪里的问题加上就好了, 能简单解释下为什么吗? 谢谢~
|
8
coderwang 2018-02-23 11:59:49 +08:00
@woshichuanqilz 不 break 循环不会中断,一直卡在 receive
|
9
woshichuanqilz OP @j0hnj shutdown 之后后面的 server 要发的东西就发不出去了。
|
10
j0hnj 2018-02-23 13:39:00 +08:00 via iPhone
@woshichuanqilz #9 TCP 是全双工的,客户端关闭写端,但是仍然可以读取服务端的响应,我这边测试是没问题的
|