socket返回值为0的问题排查
- 格式:docx
- 大小:7.91 KB
- 文档页数:1
Linux网络编程socket错误分析socket错误码:EINTR:4阻塞的操作被取消阻塞的调用打断。
如设置了发送接收超时,就会遇到这种错误。
只能针对阻塞模式的socket。
读,写阻塞的socket时,-1返回,错误号为INTR。
另外,如果出现EINTR即errno为4,错误描述Interrupted system call,操作也应该继续。
如果recv 的返回值为0,那表明连接已经断开,接收操作也应该结束。
ETIMEOUT:1101、操作超时。
一般设置了发送接收超时,遇到网络繁忙的情况,就会遇到这种错误。
2、服务器做了读数据做了超时限制,读时发生了超时。
3、错误被描述为“connect time out”,即“连接超时”,这种情况一般发生在服务器主机崩溃。
此时客户TCP 将在一定时间内(依具体实现)持续重发数据分节,试图从服务TCP 获得一个ACK 分节。
当最终放弃尝试后(此时服务器未重新启动),内核将会向客户进程返回ETIMEDOUT 错误。
如果某个中间路由器判定该服务器主机已经不可达,则一般会响应“destination unreachable”-“目的地不可达”的ICMP消息,相应的客户进程返回的错误是EHOSTUNREACH 或ENETUNREACH。
当服务器重新启动后,由于TCP 状态丢失,之前所有的连接信息也不存在了,此时对于客户端发来请求将回应RST。
如果客户进程对检测服务器主机是否崩溃很有必要,要求即使客户进程不主动发送数据也能检测出来,那么需要使用其它技术,如配置SO_KEEPALIVE Socket 选项,或实现某些心跳函数。
EAGAIN:1、Send返回值小于要发送的数据数目,会返回EAGAIN和EINTR。
2、recv 返回值小于请求的长度时说明缓冲区已经没有可读数据,但再读不一定会触发EAGAIN,有可能返回0表示TCP连接已被关闭。
3、当socket是非阻塞时,如返回此错误,表示写缓冲队列已满,可以做延时后再重试.4、在Linux进行非阻塞的socket接收数据时经常出现Resource temporarily unavailable,errno 代码为11(EAGAIN),表明在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏socket的同步,不用管它,下次循环接着recv就可以。
socket异常解决方案
《Socket异常解决方案》
在开发网络应用程序时,我们经常会遇到socket异常的问题。
socket异常可能会导致网络连接失败,数据传输中断,甚至导
致程序崩溃。
在面对这些问题时,我们需要及时解决并找出根本原因。
首先,我们需要了解造成socket异常的可能原因。
常见的原
因包括网络连接问题,服务器故障,数据包丢失等。
在了解了可能的原因后,就需要针对性地解决这些问题。
解决socket异常的方案可能包括以下几点:
1. 检查网络连接:确认网络连接是否正常,尝试其他网络环境,比如切换到4G网络或者使用VPN连接。
如果网络连接出现
问题,可能是导致socket异常的原因之一。
2. 重启服务器:如果是服务器端出现了问题,可以尝试重启服务器或者联系服务器管理员进行排查。
3. 检查数据包:数据包丢失可能会导致socket异常,对于这
种情况,我们可以使用数据包监控工具来检查数据传输情况,找出问题所在。
4. 异常处理:在程序中加入异常处理机制是很重要的,比如捕获socket异常并进行相应的处理,比如重新连接,重传数据
等。
5. 更新软件版本:有时socket异常可能是由于软件版本过低或者存在bug所致,及时更新软件版本可能解决这些问题。
总之,解决socket异常需要综合考虑网络环境、服务器端和客户端的问题,及时采取合理的措施来解决和避免出现异常情况。
希望上述的解决方案能帮助大家更好地解决socket异常的问题。
wsastartup函数的功能1. 引言在计算机网络编程中,wsastartup函数是一个重要的函数,它用于初始化 Windows Socke t(简称Winsock)库。
本文将对wsastartup函数的功能进行详细探讨,介绍其作用、使用方法和相关注意事项。
2. 什么是WinsockWinsock是Windows操作系统提供的一套用于网络编程的API(Application Programming Interface)。
它定义了一系列函数、数据结构和常量,以实现网络通信功能。
Winsock 库包含在ws2_32.dll文件中,可以在应用程序中动态链接使用。
2.1 Winsock的特点•提供TCP/IP协议栈的接口,支持主要的网络协议(如UDP、TCP、IP、ICMP 等)。
•提供了一系列函数,用于创建、管理和关闭套接字(socket),并进行网络通信。
•支持多种网络编程模型,如阻塞式编程和非阻塞式编程。
•可以用于开发各种类型的网络应用程序,如Web浏览器、邮件客户端、文件传输工具等。
2.2 Winsock的使用场景•网络服务器开发:使用Winsock库可以创建网络服务器,接收客户端请求并处理。
•网络客户端开发:使用Winsock库可以创建网络客户端,与远程服务器进行通信。
•网络编程学习:Winsock提供了丰富的网络编程接口,是学习网络编程的重要工具。
•网络通信测试与调试:Winsock库可以用于测试和调试网络通信功能。
3. wsastartup函数的作用wsastartup函数是Winsock库中的一个函数,用于初始化Winsock库。
在进行网络编程之前,需要调用wsastartup函数来初始化Winsock库的运行环境。
3.1 函数原型int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);•wVersionRequested:请求的Winsock库版本号。
“Unrecognized Windows Sockets error 0”是一个常见的Windows Socket错误,通常是由于服务器端口被占用导致的。
以下是两种常见的解决方法:
更改服务器的端口号:到Tomcat目录下的conf文件夹下,找到server.xml文件,然后修改<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />中的端口号。
例如,你可以将端口从8080更改为8088,即<Connector port="8088" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />。
关闭占用当前端口的进程:首先进入命令行,查看端口是否被占用。
运行cmd输入命令:netstat -ano。
找到占用端口的进程PID,然后通过任务管理器或taskkill程序结束该PID 的进程。
请注意,上述步骤需要管理员权限才能执行。
同时,更改服务器端口可能会影响到其他依赖于该端口的应用程序,因此在执行此操作前请确保已经充分了解其潜在影响。
此外,如果这个错误仍然存在,可能需要检查你的防火墙设置或者网络配置,确保没有阻止你的应用程序访问网络。
在某些情况下,重新安装或更新你的网络驱动程序也可能解决这个问题。
服务器中判断客户端socket断开连接的⽅法1, 如果服务端的Socket⽐客户端的Socket先关闭,会导致客户端出现TIME_WAIT状态,占⽤系统资源。
所以,必须等客户端先关闭Socket后,服务器端再关闭Socket才能避免TIME_WAIT状态的出现。
2, 在linux下写socket的程序的时候,如果尝试send到⼀个disconnected socket上,就会让底层抛出⼀个SIGPIPE信号。
client端通过 pipe 发送信息到server端后,就关闭client端, 这时server端,返回信息给 client 端时就产⽣Broken pipe 信号了。
当服务器close⼀个连接时,若client端接着发数据。
根据TCP协议的规定,会收到⼀个RST响应,client再往这个服务器发送数据时,系统会发出⼀个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。
根据信号的默认处理规则SIGPIPE信号的默认执⾏动作是terminate(终⽌、退出),所以client会退出。
若不想客户端退出可以把SIGPIPE设为SIG_IGN如: signal(SIGPIPE,SIG_IGN);这时SIGPIPE交给了系统处理。
这个信号的缺省处理⽅法是退出进程,⼤多数时候这都不是我们期望的。
因此我们需要重载这个信号的处理⽅法。
调⽤以下代码,即可安全的屏蔽SIGPIPE:struct sigaction sa;sa.sa_handler = SIG_IGN;sigaction( SIGPIPE, &sa, 0 );服务器采⽤了fork的话,要收集垃圾进程,防⽌僵⼫进程的产⽣,可以这样处理:signal(SIGCHLD,SIG_IGN); 交给系统init去回收。
这⾥⼦进程就不会产⽣僵⼫进程了。
判断连接断开的⽅法法⼀:当recv()返回值⼩于等于0时,socket连接断开。
但是还需要判断 errno是否等于 EINTR,如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。
linuxc之解决使用socket函数返回为0的问题
1、问题:
在 linux 平台下写socket,实现简单的tcp通信,服务端第一次调用 socket函数返回 0
2、找原因:
我的代码是这样写的
if ((server_sockfd = socket(AF_INET,SOCK_STREAM, 0) < 0));
特么总是返回0,日了狗
自找方法一:
到网上找为什么socket函数返回0,5分钟过去,没反应
自找方法二:
到网上找linux socket tcp编程
然后得到代码,然后输入终端测试,发现socket返回是3,日了狗,然后再去缩小范围,只执行2行代码,一行实现socket,一行打印结果,依然是3,日了狗,然后再把自己
写的代码也只执行这2行,我插,依然是0,奔溃了,难道socket 还受终端影响,不应该啊,然后果断问旁边做服务端开发的,当然也是搞安卓的,然后我让他看的时候,发现代码写错,那个< 写错位置了,尼玛,3 < 0 否,然后把0给了这个server_sockfd 为0,又因为0 不小于 0,所以代码往下执行
if ((server_sockfd = socket(AF_INET,SOCK_STREAM, 0)) < 0);
3、总结
以后千万不要犯这种傻逼问题,代码要写好。
WSAEINTR (10004)∙翻译:中断函数调用。
∙说明:阻止操作被中断通过调用WSACancelBlockingCall (Wsapiref_704y.asp)。
WSAEACCES (10013)∙翻译:权限被拒绝。
∙说明:尝试访问套接字访问权限被禁止的方式。
例如,用于发送到广播的地址,但广播的权限未设置通过使用setsockopt(SO_BROADCAST) 时,将发生此错误。
另一个可能导致WSAEACCES 错误的原因是,当调用绑定(Wsapiref_6vzm.asp)函数(在Microsoft Windows NT 4.0 Service Pack 4 [SP4] 或更高版本),另一个程序、服务或内核模式驱动程序绑定到同一地址具有独占访问权。
这种独占的访问是一项新功能的Windows NT 4.0 SP4 和更高版本,并且它使用SO_EXCLUSIVEADDRUSE 选项的实现。
WSAEFAULT (10014)∙翻译:错误的地址。
∙说明:尝试使用指针参数的调用时,系统检测到一个无效的指针地址。
如果程序传递了无效的指针值,或者如果缓冲区的长度太小,则会发生此错误。
例如,如果一个参数,它是一种SOCKADDR 结构的长度小于sizeof(SOCKADDR) 的值,将发生此问题。
WSAEINVAL (10022)∙翻译:无效的参数。
∙说明:setsockopt (Wsapiref_94aa.asp) 函数提供了无效的参数(例如,指定参数的%)。
有时,它也就是从插座的当前状态,调用例如,未在侦听的套接字接受(Wsapiref_13aq.asp)。
WSAEMFILE (10024)∙翻译:打开的文件太多。
∙说明:有太多打开的套接字。
每个实现都可能具有套接字句柄可用的最大数目。
这些句柄可能会提供每个进程的全局,或每个线程。
WSAEWOULDBLOCK (10035)∙翻译:资源暂时不可用。
∙说明:将返回此错误,无法立即完成,例如,非阻塞套接字操作从接收(Wsapiref_2i9e.asp)时无数据排队要从套接字读取。
Socket网络编程常见异常概述(1)Socket 类中有很多方法在声明时使用throws 抛出了一些异常,这些异常都是IOException 的子类。
(2)在Socket 类的方法中抛出最多的就是SocketException,其余还有七个异常可供Socket 类的方法抛出。
Java编程语言百科异常概述(1)public class IOException extends Exception这个异常是所有在Socket 类的方法中抛出的异常的父类。
(2)public class SocketException extends IOException这个异常在Socket 类的方法中使用得最频繁。
(3)public class ConnectException extends SocketExceptionConnectException 异常通常发生在由于服务器忙而未响应或是服务器相应的监听端口未打开。
(4)public class BindException extends SocketException这个异常在多个Socket 或ServerSocket 对象绑定在同一个端口,而且未打开SO_REUSEADDR选项时发生。
(5)public class NoRouteToHostException extends SocketException这个异常在遇到防火墙或是路由无法找到主机的情况下发生。
(6)public class UnknownHostException extends IOException这个异常在域名不正确时被抛出。
(7)public class ProtocolException extends IOException这个异常并不经常被抛出。
由于不明的原因,TCP/IP 的数据包被破坏了,这时将抛出ProtocolException 异常。
(8)public class SocketTimeoutException extends InterruptedIOException如果在连接超时和读取数据超时时间过后,服务器仍然未响应,connect 或read 方法抛SocketTimeoutException 异常。
socket返回值为0的问题排查
背景知识:
链路的建立,要依赖于sctp底层链路的建立。
需要配置的sctp参数包括:
本地ip、本地端口号、远端ip、远端端口号、心跳间隔、最大路径重传次数、INIT最大重传
次数、输入输出流个数等。
而建立socket是sctp建立连接的先决条件,我们使用的时socket函数创建的套接字:
int socket_id = int socket(int af, int type, int protocol);
问题现象
将配置发送给sctp链路管理模块,触发sctp的建立。
但是日志显示,利用socket建立的
socket_id为0。
通过在网上查阅了一些文章,发现socket建立的时候,socket_id是0,1,2的基本属于标准输
入输出套接字标识。
通常用户自己创建的socket不会出现这个问题。
问题原因
socket_id为0,1,2的虽然是给标准输入输出用的,但是如果我们close(0)之后,该socket_id =
0的便处于“空闲”状态。
用户利用socket函数创建套接字时,便会讲0分配给新创建的socket。
经过查找close函数使用的地方,最终定位到了一处:
1、该模块上下文初始化时,全被初始化为了0,该上下文结构体如下:
typedef struct _wireshark_global_contxt_t { .... s32 udp_sock_id; ...} wireshark_global_context_t;
2、该模块初始化时,会建立初始socket连接
该模块建立socket连接时,只允许建立一个连接,因此为了防止存在多个连接的情况,在调
用socket函数创建socket之前,加入了如下判断
if (wiresahrk_gl_ctx.udp_sock_id >= 0)
{ close(wireshark_gl_ctx.udp_sock_id);
wireshark_gl_ctx.udp_sock_id = INVALID_SOCKET; # INVALID_SOCKET = -
1}
于是就出现了close(0)的情况。
问题解决
1、上下文初始化时,将udp_sock_id初始化为非法值(-1)
2、close() socket连接的时候,判断条件为>0的情况下close。