从硬件(GPRS模块)发送时由对等方重置连接,但从PC发送时正常



tl;博士

  • 从PC和移远GPRS模块发送相同的数据
  • 从移远通信发送时,服务器会引发异常Connection reset by peer
  • 但移远通信在具有相同EC2-micro实例和负载均衡器的生产环境中工作。
  • 除了移远,另一个GPRS模块 - Neoway M680 - 可与此EC2实例配合使用。

设置

本地 - 设置
我有一个移远M66,一个GPRS模块,我用它来连接到服务器(AWS EC2)并传输一些数据。
我还有一个python script,用于使用 PC 连接和发送相同的数据。下面是 python 脚本

import socket
import sys
from io import open
from time import sleep
'''
Python script to send data to remote server
'''
#replace address with the remote server address
HOST, PORT = '127.0.0.1', 3000 
if len(sys.argv) < 2:
error = "Error:"
print("{} {}".format(error, "Pass in the file to be send"))
exit(1)
filename = sys.argv[1]
with open(filename, "r", newline="r") as f:
lines = f.readlines()
data = "".join(lines)
# Create a socket (SOCK_STREAM means a TCP socket)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
# Connect to server and send data
sock.connect((HOST, PORT))
sock.sendall(bytes(data, "utf-8"))
# Receive data from the server and shut down
received = r"{}".format(sock.recv(1024))
sock.close()
print("Received: {}".format(received))

远程 - 设置
我正在运行一个EC2-micro实例,该实例正在运行一个python脚本,该脚本仅侦听端口并打印其接收的数据,还发送硬编码的响应。这是脚本

#!/usr/bin/env python3
'''
Python code running on EC2-micro
'''
import socket
import errno
from datetime import datetime
print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
HOST = '0.0.0.0'  # Standard loopback interface address (localhost)
PORT = 3000       # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
try:
data = r"{}".format(conn.recv(1024))
print("Received: {}".format(data))
#respond back with $E0A0
conn.sendall(bytes("$E0A0:8Br$E0FFr", "utf-8"))
conn.close()
s.close()
break
except socket.error as e:
if e.errno != errno.ECONNRESET:
raise
if e.errno == errno.ECONNRESET:
printf("Connection reset by peer error again")
raise #it is failing here
pass

测试

移远智能GPRS模块

当我尝试使用Quectel模块发送数据时,使用AT Commands,我从硬件 (quectel) 端看到的是连接已被CLOSED

17:29:05.652 [Tx] AT+QIOPEN="TCP","127.0.0.1",3000r
17:29:05.672 [Rx] rnOKrnrnCONNECT OKrn
17:29:07.699 [Tx] AT+SEND=1r
17:29:07.718 [Rx] >
17:29:08.603 [Tx] A
17:29:08.647 [Rx] rnSEND OKrn
17:29:09.446 [Rx] CLOSED

在 EC2 上运行的代码崩溃并显示:

Connection reset by peer error again
Traceback (most recent call last):
File "./server.py", line 22, in <module>
data = r"{}".format(conn.recv(1024))
ConnectionResetError: [Errno 104] Connection reset by peer

但是当我使用 python 脚本(上面给出的第一个代码)进行测试时,这不会发生

从PC
运行python脚本

$ python client.py data
Received: b'$E0A0:8Br$E0FFr'

更多观察:

  • 此硬件 (quectel) 正在生产环境中使用,并且按预期在那里工作。只有在这个新的独立实例(没有load balancing)中,它才会失败并显示Connection reset by peer
  • 我了解到这可能是因为(从这里)
    • 服务器端资源限制
    • 高流量
  • 但是这个新实例不执行任何其他操作。我还检查了CloudWatch没有看到 CPU 使用率激增

问题

  1. 您认为这是服务器端的问题吗?
    • 由于移远通信模块响应了SEND OK,从文档中我们可以确定数据已离开模块。TCP承诺提供数据
    • 但显然,在接收/读取数据之前,我们会得到Connection reset by peer
  2. 是性能/基础结构问题吗?
    • 我能找到的听起来合理的只是服务器可能较少的内存或其他资源

这是一个后端问题。端口白名单问题。

相关内容

最新更新