Socket连接异常及Connection reset by peer的原因解析

在网络编程当中,Socket异常是较为常见的问题。要是这些异常没有被及时处理,就会对程序的稳定运行产生严重影响。下面会为大家详细剖析几种常见的Socket异常。

异常基础规则

Socket默认的连接时长为60秒,在这60秒里,如果没有像读写数据这样的心跳交互,连接就会自动关闭,这是很多Socket异常出现所依据的一个基础性规则,比如在一些数据交互频率低的场景中,就容易因为这个时间限制致使连接自动断开,为避免连接自动关闭,就需要在60秒内开展有效的数据读写操作。

Connect reset by peer

若一端的Socket被关闭,这关闭情况分为主动关闭和因异常退出而关闭两种。当另一方仍发送数据时,发送的第一个数据包就会引发这个异常。存在这样一种情况,某系统中客户端突然崩溃退出,进而致使Socket关闭。而服务器端并不知情,依旧在发送数据,这样便触发了这个异常。遇到这种问题时,要去检查Socket关闭的原因,避免在自己不知情的情况下继续发送数据。

Connection reset

一端退出后,没有关闭连接。这时另一端在读取连接中的数据时,就会抛出这个异常。当网络连接通过防火墙时,因为防火墙有超时机制,长时间没有数据传输,就会关闭TCP会话。之后再进行读写操作,就会导致此异常。比如说,某公司网络通过防火墙,一段代码由于长时间未发送数据,导致会话被关闭,再读取数据时就报错了。需要留意防火墙的设置以及网络连接的数据传输情况。

ServerSocket创建异常

该异常出现在服务器端执行new ServerSocket(port)操作时,port是整型值,取值范围为0到65536 。这个异常常因端口被占用或服务未启动导致。在某个项目中,服务器启动新的ServerSocket时,因端口被其他程序占用而报错。可以通过查看端口占用情况,释放被占用的端口。

客户端进行new Socket(ip, port)操作时会出现异常,原因有两个。一个原因是,具有该ip地址的机器找不到,这表明从当前机器到指定ip没有路由。另一个原因是,该ip存在,然而找不到指定的端口进行监听。曾经有客户端在连接服务器时,由于ip地址写错而无法连接。我们要仔细检查客户端的ipport是否正确。

Socket is closed

该异常有可能在客户端发生,也有可能在服务器端发生,这是由于己方主动关闭连接之后,又对网络连接做了读写操作。在调试程序的时候,客户端先关闭了Socket,接着又尝试发送数据,从而触发了这个异常。主动关闭连接后,就不要再进行读写操作了。

def test_main():
    s_conn = pika.BlockingConnection(
        pika.ConnectionParameters('127.0.0.1', 
            heartbeat_interval=10,
            socket_timeout=5,
            credentials=pika.PlainCredentials(USER, PWD)))
    # ....

异常处理方法

:param int heartbeat_interval: How often to send heartbeats.
                                  Min between this value and server's proposal
                                  will be used. Use 0 to deactivate heartbeats
                                  and None to accept server's proposal.

出现问题后,要先检查客户端的ip是否正确,还要检查客户端的port是否正确。若两者都正确,就从客户端ping一下服务器,看看能不能ping通。要是服务器把ping禁掉,那就需要用其他方法。若能ping通,接着看服务器端监听指定端口的程序有没有启动。在某项目中,按照这个流程排查,很快就解决了Socket连接异常问题。

大家遇到上述这类Socket异常的时候,有没有尝试过其他解决办法?如果尝试过,欢迎在评论区分享你的经验,还请点赞并且分享这篇文章,这样能让更多人获取这些实用信息!

import threading,time
#开启一个线程,每隔20s,执行一次心跳
 def timesleep(n):
     for i in range(n):
         time.sleep(20)
         # heartbeat=0,意味着不检测心跳,server端将不会主动断开连接。但是并不起作用,
         # process_data_events 方法,类似 heartbeat 操作,可以保持与 rabbitmq 的通信。
         # 在执行长时间任务时,定时调用 process_data_events 方法,就不会丢失连接
         self.connection.process_data_events()
 message_thread = threading.Thread(target=timesleep, args=(3600*24,))
 message_thread.start()

作者头像
tp钱包创始人

tp钱包

上一篇:深入解析PI网络045版本PI节点搭建的全流程及常见问题
下一篇:深入剖析TP火币生态链钱包:特点、功能及数字资产管理重要性

发表评论