繁体   English   中英

从硬件(GPRS模块)发送时由对等体重置连接,但从PC发送时则很好

[英]Connection reset by peer when sending from hardware (GPRS module) but fine when send from PC

TL;博士

  • 从PC和Quectel GPRS模块发送相同的数据
  • 从Quectel发送时,服务器引发异常Connection reset by peer
  • 但是Quectel在具有相同EC2-micro实例和负载均衡器的生产环境中工作。
  • 除了Quectel之外,另一个GPRS模块--Neoway M680 - 适用于这个EC2实例。

设定

本地 - 设置
我有一个Quectel 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))

远程 - 设置
我正在运行一个运行python脚本的EC2-micro实例,它只是监听一个端口并打印它收到的数据,同时发送一个硬编码的响应。 这是脚本

#!/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:8B\r$E0FF\r", "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

测试

Quectel GPRS模块

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

17:29:05.652 [Tx] AT+QIOPEN="TCP","127.0.0.1",3000\r
17:29:05.672 [Rx] \r\nOK\r\n\r\nCONNECT OK\r\n
17:29:07.699 [Tx] AT+SEND=1\r
17:29:07.718 [Rx] >
17:29:08.603 [Tx] A
17:29:08.647 [Rx] \r\nSEND OK\r\n
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:8B\r$E0FF\r'

更多观察:

  • 这个硬件(quectel)正在生产环境中使用,它按预期在那里工作。 只有在这个新的独立实例中(没有load balancing ),它才会失败,同时Connection reset by peer
  • 我了解到这可能是因为(从这里
    • 服务器端的资源限制
    • 交通拥挤
  • 但是这个新实例没有做任何其他事情。 我还检查了CloudWatch没有看到CPU使用率的高峰

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM