socket编程过程中往往会遇到这样那样的问题,出现了这些问题,有的是由于并发访问量太大造成的,有些却是由于代码中编程不慎造成的。比如说,最常见的错误就是程序中报打开的文件数过多这个错误。socket建立连接的时候是三次握手,这个大家都很清楚,但是socket关闭连接的时候,需要进行四次挥手,但很多人对于这四次挥手的具体流程不清楚,吃了很多亏。
-
ret = CS_GetConnect(&client,ipAddr,
9010);
-
if (ret ==
0) {
-
printf(
"connected success.");
-
}
-
CloseSocket(client);
代码片段1.1
基本逻辑就是,连接建立后立即关闭。其中CloseSocket函数是自定义函数,仅仅封装了在windows和linux下关闭socket的不同实现而已
-
#if defined(WIN32) || defined(WIN64)
-
#define CloseSocket(fd) do{ closesocket(fd);/* shutdown(fd, 2);*/ }while(0)
-
#else
-
#define CloseSocket(fd) do{ close(fd); /*shutdown(fd,2);*/ }while(0)
-
#endif
代码片段1.2
那么怎样预防SOCKET处于CLOSE_WATI状态呢,答案在这里:
-
while(
true) {
-
memset(getBuffer,
0,MY_SOCKET_BUFFER_SIZE);
-
Ret = recv(client, getBuffer, MY_SOCKET_BUFFER_SIZE,
0);
-
if ( Ret ==
0 || Ret == SOCKET_ERROR )
-
{
-
printf(
"对方socket已经退出,Ret【%d】!\n",Ret);
-
Ret = SOCKET_READE_ERROR;
//接收服务器端信息失败
-
break;
-
}
-
}
-
-
clear:
-
if (getBuffer !=
NULL) {
-
free(getBuffer);
-
getBuffer =
NULL;
-
}
-
closesocket(client);
代码片段1.3
-
int
on =
1;
-
if (setsockopt(socketfd
/*socket句柄*/,SOL_SOCKET,SO_REUSEADDR,(
char *)&
on,
sizeof(
on)))
-
{
-
return ERROR_SET_REUSE_ADDR;
-
}
代码片段2.1
-
struct linger so_linger;
-
so_linger.l_onoff =
1;
-
so_linger.l_linger =
10;
-
if (setsockopt(socketfd,SOL_SOCKET,SO_LINGER,(
char *)&so_linger,
sizeof(
struct linger)))
-
{
-
return ERROR_SET_LINGER;
-
}
代码片段2.2
-
Socket client =
new Socket();
//,9090
-
try {
-
client.connect(
-
new InetSocketAddress(
"192.168.56.101",
9090));
-
-
while(
true){
-
int c = client.getInputStream().read();
-
if (c >
0) {
-
System.
out.print((
char) c);
-
}
else {
//如果对方socket关闭,read函数返回-1
-
break;
-
}
-
-
try {
-
Thread.currentThread().sleep(
2000);
-
}
catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
}
catch (IOException e2) {
-
e2.printStackTrace();
-
}
finally {
-
try {
-
client.close();
-
}
catch (IOException e) {
-
e.printStackTrace();
-
}
-
}
-
-
}
代码片段3.1
4.通信的过程中,socket双发中有一方的进程意外退出,则这一方将向其对应的另一方发送RST消息,所有双发建立的连接将会被回收,未接收完的消息就会被丢弃。
5.项目的配套代码可以从这里得到http://git.oschina.net/yunnysunny/socket_close