簡體   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