100分求助,SOCKET重新连接的问题

kapil 2012-06-13 09:52:44
下面的代码是连接SOCKET服务器的代码,如何判断SOCKET是否断开?如果断开后自动重连的代码改如何写呢?

----------------------
string socket_ip = "127.0.0.1";

int socket_port = 19001;

if (err)
{
printf("客户端的嵌套字打开失败!\n");
return 0;//结束
}

SOCKET clientSocket=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN clientsock_in;
clientsock_in.sin_addr.S_un.S_addr=inet_addr(socket_ip.c_str());
clientsock_in.sin_family=AF_INET;
clientsock_in.sin_port=htons(socket_port);
//bind(clientSocket,(SOCKADDR*)&clientsock_in,strlen(SOCKADDR));//注意第三个参数
//listen(clientSocket,5);
connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR));//开始连接

------------------

多谢?
...全文
339 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
cobra_chen 2012-06-13
  • 打赏
  • 举报
回复
服务端无法修改么?
如果是这样,我只能提供一个思路。
在另外的线程或者进程去检查这个socket是否可写。
可以参考select
或者还有其他的检测手段。
-
最好的办法是服务端也做修改。
客户端长时间的阻塞也不是很好。
虽然阻塞模式会让编码变的简单,但是扩展性会差很多。
如果本来就要实现很简单的功能,阻塞模式也是相当好的。
关键看需要用来解决什么问题。

[Quote=引用 15 楼 的回复:]

引用 14 楼 的回复:

如果处理数据会消耗时间很长(5min以上我觉得就比较长了,这个时间看需要更改)。
那么就可以考虑使用多线程,或者多进程,用另外的进程或线程处理数据。
如果再处理数据中,那么程序就无法保证一定连接。
或者另起线程或进程保证连接。
-
重连接的话最简单的方法:关闭现有的socket。重新建立socket。
引用 13 楼 的回复:

引用 10 楼……
[/Quote]
kapil 2012-06-13
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

如果处理数据会消耗时间很长(5min以上我觉得就比较长了,这个时间看需要更改)。
那么就可以考虑使用多线程,或者多进程,用另外的进程或线程处理数据。
如果再处理数据中,那么程序就无法保证一定连接。
或者另起线程或进程保证连接。
-
重连接的话最简单的方法:关闭现有的socket。重新建立socket。
引用 13 楼 的回复:

引用 10 楼 的回复:

引用 8 楼 ……
[/Quote]

请问在while中如何判断SOCKET是否还连接着呢?

我这个是SOCKET客户端,服务器端不给客户端发送任何的数据。
cobra_chen 2012-06-13
  • 打赏
  • 举报
回复
如果处理数据会消耗时间很长(5min以上我觉得就比较长了,这个时间看需要更改)。
那么就可以考虑使用多线程,或者多进程,用另外的进程或线程处理数据。
如果再处理数据中,那么程序就无法保证一定连接。
或者另起线程或进程保证连接。
-
重连接的话最简单的方法:关闭现有的socket。重新建立socket。
[Quote=引用 13 楼 的回复:]

引用 10 楼 的回复:

引用 8 楼 的回复:

引用 7 楼 的回复:

不是啊,客户端不需要bind,直接connect就行了。


是这样的,上面一段代码是我连接服务器的逻辑,在连接之后我会进行一些操作,如果在操作的时候如何判断socket是否还在连接状态?如果发现断掉了,就重新连接呢?


任何SOCKET的操作出现不可挽回(FATAL)的就重连,比如r……
[/Quote]
kapil 2012-06-13
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

引用 8 楼 的回复:

引用 7 楼 的回复:

不是啊,客户端不需要bind,直接connect就行了。


是这样的,上面一段代码是我连接服务器的逻辑,在连接之后我会进行一些操作,如果在操作的时候如何判断socket是否还在连接状态?如果发现断掉了,就重新连接呢?


任何SOCKET的操作出现不可挽回(FATAL)的就重连,比如recv,send时候返回错误,并且……
[/Quote]

可能是我没说明白,我把我的代码大概秒数一下:

string socket_ip = "127.0.0.1";

int socket_port = 19001;

if (err)
{
printf("客户端的嵌套字打开失败!\n");
return 0;//结束
}

SOCKET clientSocket=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN clientsock_in;
clientsock_in.sin_addr.S_un.S_addr=inet_addr(socket_ip.c_str());
clientsock_in.sin_family=AF_INET;
clientsock_in.sin_port=htons(socket_port);
connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR));//开始连接

while(true)
{
// 这里会循环处理很多数据,时间很长,需要一整天
}

// 最后关闭连接
KSFTHQPUB_Stop();

closesocket(clientSocket);
WSACleanup();

我现在遇到的问题是,在while循环中如何判断socket是否连接?如果发现socket已经断开再自动重连,重连的代码该怎么写呢?
cobra_chen 2012-06-13
  • 打赏
  • 举报
回复
确认是否连接,可以发送心跳包。

[Quote=引用 8 楼 的回复:]

引用 7 楼 的回复:

不是啊,客户端不需要bind,直接connect就行了。


是这样的,上面一段代码是我连接服务器的逻辑,在连接之后我会进行一些操作,如果在操作的时候如何判断socket是否还在连接状态?如果发现断掉了,就重新连接呢?
[/Quote]
cobra_chen 2012-06-13
  • 打赏
  • 举报
回复
并且errno不可容忍此话怎讲?
[Quote=引用 10 楼 的回复:]

引用 8 楼 的回复:

引用 7 楼 的回复:

不是啊,客户端不需要bind,直接connect就行了。


是这样的,上面一段代码是我连接服务器的逻辑,在连接之后我会进行一些操作,如果在操作的时候如何判断socket是否还在连接状态?如果发现断掉了,就重新连接呢?


任何SOCKET的操作出现不可挽回(FATAL)的就重连,比如recv,send时候返回错误,并且……
[/Quote]
qq120848369 2012-06-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

引用 7 楼 的回复:

不是啊,客户端不需要bind,直接connect就行了。


是这样的,上面一段代码是我连接服务器的逻辑,在连接之后我会进行一些操作,如果在操作的时候如何判断socket是否还在连接状态?如果发现断掉了,就重新连接呢?
[/Quote]

任何SOCKET的操作出现不可挽回(FATAL)的就重连,比如recv,send时候返回错误,并且errno不可容忍。
cobra_chen 2012-06-13
  • 打赏
  • 举报
回复
用send发送心跳包。

[Quote=引用 8 楼 的回复:]

引用 7 楼 的回复:

不是啊,客户端不需要bind,直接connect就行了。


是这样的,上面一段代码是我连接服务器的逻辑,在连接之后我会进行一些操作,如果在操作的时候如何判断socket是否还在连接状态?如果发现断掉了,就重新连接呢?
[/Quote]
kapil 2012-06-13
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

不是啊,客户端不需要bind,直接connect就行了。
[/Quote]

是这样的,上面一段代码是我连接服务器的逻辑,在连接之后我会进行一些操作,如果在操作的时候如何判断socket是否还在连接状态?如果发现断掉了,就重新连接呢?
qq120848369 2012-06-13
  • 打赏
  • 举报
回复
不是啊,客户端不需要bind,直接connect就行了。
艳琦罗生 2012-06-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 1 楼 的回复:

//bind(clientSocket,(SOCKADDR*)&clientsock_in,strlen(SOCKADDR));//注意第三个参数

你别口口声声喊着第三个参数,结果给一个错的第三个参数,你运气好IPV4的addr和SOCKADDR长度一样,碰到IPV6你还传这个SOCKADDR,你就等死吧。

bind(clientSoc……
[/Quote]
socket 不会判断断开重连 自能自己 发现断开 重新做连接
kapil 2012-06-13
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

//bind(clientSocket,(SOCKADDR*)&clientsock_in,strlen(SOCKADDR));//注意第三个参数

你别口口声声喊着第三个参数,结果给一个错的第三个参数,你运气好IPV4的addr和SOCKADDR长度一样,碰到IPV6你还传这个SOCKADDR,你就等死吧。

bind(clientSocket,(SOCKADDR*)&……
[/Quote]

十分感谢回复!

上面这个代码是从网上找到的,我本人对C++还是小白。

如果加上了这一行,是不是如果断开了,程序会自动连接?

bind(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR_IN));
xiao0915 2012-06-13
  • 打赏
  • 举报
回复
WSAGetLastError()
艳琦罗生 2012-06-13
  • 打赏
  • 举报
回复
CMySock::BindSock()
{
sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(4444);

int opt = 1;
int ret = setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR,
(const char*)&opt, sizeof(opt));
if (ret == SOCKET_ERROR)
return -1;

ret=bind(m_sock,(sockaddr *)&servaddr,sizeof(servaddr));
if (ret == SOCKET_ERROR)
int err = WSAGetLastError();

return 0;
}
cobra_chen 2012-06-13
  • 打赏
  • 举报
回复
楼上说的对。
-
如果连接断开,那么在recv或者send的时候就会失败,window的话可以调用WSAGetLastError(),查看错误代码。linux用errno。
qq120848369 2012-06-13
  • 打赏
  • 举报
回复
//bind(clientSocket,(SOCKADDR*)&clientsock_in,strlen(SOCKADDR));//注意第三个参数

你别口口声声喊着第三个参数,结果给一个错的第三个参数,你运气好IPV4的addr和SOCKADDR长度一样,碰到IPV6你还传这个SOCKADDR,你就等死吧。

bind(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR_IN));
connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR_IN));//开始连接
KING_314 2012-06-13
  • 打赏
  • 举报
回复

BOOL CTcpip::Tcp_ClientOpenInet(unsigned long ip, unsigned short port)
{
struct sockaddr_in server;
int rval;
unsigned long argp = 1;

struct timeval tv;
char errmsg[255];
fd_set fd;
fd_set readfd;
time_t t1, t2 ;
unsigned char * p;

memcpy(&(server.sin_addr), &ip, sizeof(server.sin_addr));
server.sin_port = htons(port);
server.sin_family = AF_INET;

clisock = socket(AF_INET, SOCK_STREAM, 0);
if (clisock < 0)
{
/* sockid == -1 */
sprintf(errmsg, "Client: socket() create. with error %d",
WSAGetLastError());
DebugLog(errmsg);
return FALSE;
}

ioctlsocket(clisock, FIONBIO, &argp);
FD_ZERO(&fd);
FD_ZERO(&readfd);

time(&t1) ;
t2 = t1 + 5 ;

while (WaitForSingleObject(gReadDataEvent, 30) != WAIT_OBJECT_0)
{
rval = connect(clisock, (struct sockaddr *) &server, sizeof(server)) ;
if (rval != 0)
{
FD_SET(clisock, &fd);
tv.tv_sec = 0; //gwcfg.timeout;
tv.tv_usec =5000L; //500000L;

FD_SET(clisock, &readfd);
tv.tv_sec = 0;
tv.tv_usec = 5000L;
if ((rval = select(0, &readfd, &fd, NULL, &tv)) <= 0)
{
if (rval == SOCKET_ERROR)
{
int Error = WSAGetLastError();
switch(Error)
{
case WSANOTINITIALISED:
break;
case WSAEFAULT: //currently ignore this condition
TRACE(_T("WARNING: MAX. Message Size exceeded\n"));
break;
case WSAENETDOWN:
break;
default:
{
TCHAR buffer[512];
wsprintf(buffer, _T("SendTo() returned %d"), Error);
}
break;
}
}
time(&t1) ;
if (t1 > t2)
{
/* time out */
closesocket(clisock);
p = (unsigned char *) &ip;
return FALSE ;
}
}
else
{
argp = 0; // none block
if (!AsyncMode)
ioctlsocket(clisock, FIONBIO, &argp);
return TRUE;
}
}
else
{
argp = 0; // none block
if (!AsyncMode)
ioctlsocket(clisock, FIONBIO, &argp);
return TRUE;
}
}
return FALSE;
#endif
}

KING_314 2012-06-13
  • 打赏
  • 举报
回复

BOOL CTcpip::Tcp_ClientOpenInet(unsigned long ip, unsigned short port)
{
struct sockaddr_in server;
int rval;
unsigned long argp = 1;

struct timeval tv;
char errmsg[255];
fd_set fd;
fd_set readfd;
time_t t1, t2 ;
unsigned char * p;

memcpy(&(server.sin_addr), &ip, sizeof(server.sin_addr));
server.sin_port = htons(port);
server.sin_family = AF_INET;

clisock = socket(AF_INET, SOCK_STREAM, 0);
if (clisock < 0)
{
/* sockid == -1 */
sprintf(errmsg, "Client: socket() create. with error %d",
WSAGetLastError());
DebugLog(errmsg);
return FALSE;
}

ioctlsocket(clisock, FIONBIO, &argp);
FD_ZERO(&fd);
FD_ZERO(&readfd);

time(&t1) ;
t2 = t1 + 5 ;

while (WaitForSingleObject(gReadDataEvent, 30) != WAIT_OBJECT_0)
{
rval = connect(clisock, (struct sockaddr *) &server, sizeof(server)) ;
if (rval != 0)
{
FD_SET(clisock, &fd);
tv.tv_sec = 0; //gwcfg.timeout;
tv.tv_usec =5000L; //500000L;

FD_SET(clisock, &readfd);
tv.tv_sec = 0;
tv.tv_usec = 5000L;
if ((rval = select(0, &readfd, &fd, NULL, &tv)) <= 0)
{
if (rval == SOCKET_ERROR)
{
int Error = WSAGetLastError();
switch(Error)
{
case WSANOTINITIALISED:
break;
case WSAEFAULT: //currently ignore this condition
TRACE(_T("WARNING: MAX. Message Size exceeded\n"));
break;
case WSAENETDOWN:
break;
default:
{
TCHAR buffer[512];
wsprintf(buffer, _T("SendTo() returned %d"), Error);
}
break;
}
}
time(&t1) ;
if (t1 > t2)
{
/* time out */
closesocket(clisock);
p = (unsigned char *) &ip;
return FALSE ;
}
}
else
{
argp = 0; // none block
if (!AsyncMode)
ioctlsocket(clisock, FIONBIO, &argp);
return TRUE;
}
}
else
{
argp = 0; // none block
if (!AsyncMode)
ioctlsocket(clisock, FIONBIO, &argp);
return TRUE;
}
}
return FALSE;
#endif
}

cobra_chen 2012-06-13
  • 打赏
  • 举报
回复
server端去connect client端?
另不明白楼主代码是否是连续的代码,
或者只是代码片段?
建议楼主搜一些socket的文章看一看吧。
先要了解其工作机制。
磨刀不误砍柴工。

[Quote=引用 17 楼 的回复:]

引用 16 楼 的回复:

服务端无法修改么?
如果是这样,我只能提供一个思路。
在另外的线程或者进程去检查这个socket是否可写。
可以参考select
或者还有其他的检测手段。
-
最好的办法是服务端也做修改。
客户端长时间的阻塞也不是很好。
虽然阻塞模式会让编码变的简单,但是扩展性会差很多。
如果本来就要实现很简单的功能,阻塞模式也是相当好的。
关键看需要用来解……
[/Quote]
kapil 2012-06-13
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 的回复:]

服务端无法修改么?
如果是这样,我只能提供一个思路。
在另外的线程或者进程去检查这个socket是否可写。
可以参考select
或者还有其他的检测手段。
-
最好的办法是服务端也做修改。
客户端长时间的阻塞也不是很好。
虽然阻塞模式会让编码变的简单,但是扩展性会差很多。
如果本来就要实现很简单的功能,阻塞模式也是相当好的。
关键看需要用来解决什么问题。

引用 15 楼……
[/Quote]

我已经把SERVER端修改了,是用JAVA写的

下面是在WHILE中添加的测试代码:


closesocket(clientSocket); // 手动关闭连接

// 接收数据的长度
receive_length = recv(clientSocket, recvbuf, sizeof(recvbuf), 0);

cout << receive_length << endl;

// 如果长度为0,就判断为连接断开,需要重新连接
if(receive_length < 0)
{
//closesocket(clientSocket);
cout << "reconnecting.." << endl;

connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR));//开始连接
}

调试后发现,SOCKET已经关闭,输出的长度为-1,但是仍然不能自动连接,是哪里的问题呢?
内容概要:本文提出了一种基于加权稀疏矩阵恢复与加速交替方向乘子法(ADMM)的单通道盲解混响算法,并提供了完整的Matlab代码实现。该方法旨在从仅有的单路接收信号中有效离出原始声源信号,克服传统多通道方法对硬件的依赖。核心技术结合了信号在时频域的稀疏性先验,通过构建加权机制以增强稀疏矩阵恢复的准确性,并引入加速ADMM算法来优化求解过程,显著提升了算法的收敛速度与计算效率。该算法特别适用于麦克风阵列受限或无法部署的复杂声学环境,能够有效抑制混响干扰,从而显著提升语音信号的清晰度与后续语音识别系统的性能。; 适合人群:具备扎实的数字信号处理、凸优化理论及稀疏表示基础,从事音频信号处理、语音增强、盲源离或相关领域研究与开发工作的研究生、科研人员及工程技术人员。; 使用场景及目标:①解决单麦克风场景下的语音混响去除难题,提升语音通信质量;②应用于智能助听器、车载语音系统、远程视频会议、人机交互等存在严重混响的实际应用场景;③为盲解卷积、稀疏信号恢复等领域的研究提供一种高效的算法实现范例与优化思路。; 阅读建议:建议读者在深入理解信号稀疏性、ADMM优化框架等理论基础上,结合所提供的Matlab代码进行实践,重点析加权策略的设计原理及其对恢复性能的影响,并通过调整正则化参数、权重因子等关键变量,探究其在不同混响强度和噪声条件下的鲁棒性与泛化能力。
内容概要:本文介绍了一个基于Simulink的永磁同步电机(PMSM)电流环控制策略仿真模型,重点实现了二阶滑模控制(STSMC)、有限集模型预测控制(FCS-MPC)和PI控制三种先进控制算法。该模型通过构建完整的电机驱动系统仿真环境,对比析了不同控制方法在动态响应速度、抗干扰能力、稳态精度以及鲁棒性等方面的性能表现,验证了各算法在高性能电机驱动应用中的可行性与优势。文档内容涵盖控制器设计、参数整定、仿真结果析及系统稳定性评估,具有较强的可复现性和拓展性,适用于先进控制算法的教学演示、科研验证与工程原型开发。; 适合人群:具备一定电机控制理论基础和Simulink仿真经验的电气工程、自动化、控制科学与工程等相关专业的研究生、科研人员以及从事电机驱动系统研发的工程师。; 使用场景及目标:①开展永磁同步电机先进电流控制策略的仿真研究与性能对比;②深入理解滑模控制、模型预测控制与传统PI控制的原理与实现差异;③支撑毕业设计、科研课题或工业项目中控制算法的选型、验证与优化工作。; 阅读建议:此资源以Simulink仿真实现为核心,建议读者结合现代控制理论教材与仿真模型同步操作,重点关注各控制器的结构设计、参数调节过程及仿真响应曲线,通过对比析深入掌握不同控制策略的作用机制与适用条件,并可在此基础上进行算法改进与功能扩展。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧