客户端Socket连接,老是要重启一下网卡,客户端Socket连接才能正常呢
服务器上要主动建立多个客户端固定的连接到134网段的每个终端,每个客户端连接使用一个线程,在线程里这大致这样实现连接采集数据的:
1、skt := Socket(AF_INET, SOCK_STREAM, IPPROTO_IP)
2、 Connect(skt, addr, sizeof(addr))
3、循环采集数据 recv、send
4、CloseSocket(skt);
5、在主程序启动和退出时分别调用了WSAStartup(MAKEWORD(2, 2), MyWSA)、 WSACleanup()
目前问题是:
每次程序启动,刚开始能连接134网段上的终端收发数据,然后不到一分钟就这个连接就不能收发数据,线程中重新连接机制,但重新连接不上,这时连接的错误代码是10060。
这个时候我在系统中用另外的测试工具也连接不上那个终端,如果我让这个客户端线程退出,测试工具又能连接上那个终端。
如果当程序重新连接不上终端时,我禁用、再启用一下134网卡,这时连接就恢复正常了,能正常收发数据。
采集线程代码如下:
procedure TClientSocketPortThread.SocketCollect; //Socket采集
var
skt: TSOCKET; //创建Socket对象
addr: TSockAddr; //地址信息
tmpStr: string;
tModul: TContrlModule;
SocketAddr: string;
SocketPort: Integer;
SocketErroFlag: Byte;
i, CollectResult: Integer;
CollectFailCount, OpenSocketErrorCount: Integer; //采集次数, 失败次数
begin
SocketAddr := '';
SocketPort := 0;
if Pos(',', FCommPara) > 1 then
begin
try
SocketAddr := Copy(FCommPara, 1, Pos(',', FCommPara) - 1);
SocketPort := StrToInt(Copy(FCommPara, Pos(',', FCommPara) + 1, Length(FCommPara) - Pos(',', FCommPara)));
except on E: Exception do
begin
tmpStr := FName + ':' + '分解CommPara出错!' + E.Message;
OutMess(tmpStr, 'COM');
WriteSystemLog(tmpStr);
end;
end;
end;
while (not FCloseFlag) and (not Terminated) do
begin
try
ZeroMemory(@addr, sizeof(addr));
Addr.sin_family := AF_INET;
Addr.sin_addr.S_addr := inet_addr(PChar(SocketAddr));
Addr.sin_port := Htons(SocketPort);
//建立Socket句柄
UpdateListInfo(3, '准备建立Socket');
skt := Socket(AF_INET, SOCK_STREAM, IPPROTO_IP); //IPPROTO_TCP);
if (skt = INVALID_SOCKET) then
begin
mySleep(5000);
Continue;
end;
try
OpenSocketErrorCount := 0;
while (not FCloseFlag) and (not Terminated) do
begin
// 建立连接
SocketErroFlag := Connect(skt, addr, sizeof(addr));
if (SocketErroFlag <> 0) then
begin
for i := 0 to FModulList.Count - 1 do //置此串口采集所有模块采集故障
begin
tModul := FModulList[i];
tModul.SeriesCollectFailCount := tModul.SeriesCollectFailCount + 1;
if tModul.SeriesCollectFailCount >= tModul.MaxCollectFailCount then
begin
tModul.SetCollectErro;
RefreshModulImage(tModul); //刷新图标状态
end;
end;
Inc(OpenSocketErrorCount);
tmpStr := FName + ':连续' + IntToStr(OpenSocketErrorCount) + '次打开Socket连接失败! 地址:' + SocketAddr + ' 端口:' + IntToStr(SocketPort) + ' 错误代码:' + IntToStr(WSAGetLastError);
UpdateListInfo(3, '连续' + IntToStr(OpenSocketErrorCount) + '次打开Socket连接失败, 错误代码:' + IntToStr(WSAGetLastError)); //FListItem.SubItems[1] := '打开Socket连接失败';
OutMess(tmpStr, 'COM');
if not FilterSocketConnectErrorLog then
WriteSystemLog(tmpStr);
mySleep(2000);
if OpenSocketErrorCount >= 5 then //连续5次打开错误
begin
UpdateListInfo(3, tmpStr);
raise Exception.Create(tmpStr);
end;
Continue;
end;
tmpStr := FName + ':打开Socket连接成功! 地址:' + SocketAddr + ' 端口:' + IntToStr(SocketPort);
UpdateListInfo(3, '打开Socket连接成功'); //FListItem.SubItems[1] := '打开Socket连接成功';
OutMess(tmpStr, 'COM');
WriteSystemLog(tmpStr);
mySleep(1000);
//开始轮询采集
CollectFailCount := 0;
while (not FCloseFlag) and (not Terminated) do
begin
for i := 0 to FModulList.Count - 1 do
begin
tModul := FModulList[i];
tModul.Handle := skt;
UpdateListInfo(3, '空闲');
RefreshModulImage(tModul);
if (tModul.Enabeled) and (tModul.CommNo = FCommID) then
begin
tModul.ExeCmd; //先执行命令
if tModul.CollectTime > Now then //防止系统日期改变后不会采集
tModul.CollectTime := Now;
if Abs((Now - tModul.CollectTime) * 24 * 60 * 60) >= tModul.ColltIntval then //达到采集间隔执行采集
begin
UpdateListInfo(2, tModul.Name);
UpdateListInfo(3, '开始采集');
OutMess('采集模块索引号:' + IntToStr(tModul.IndexNo) + '开始采集', tModul.IndexNo);
StartCollect(tModul, CollectResult);
if CollectResult <> 0 then
begin
Inc(CollectFailCount);
UpdateListInfo(3, '采集失败');
OutMess('采集模块索引号:' + IntToStr(tModul.IndexNo) + '采集失败', tModul.IndexNo);
OutMess('采集模块索引号:' + IntToStr(tModul.IndexNo) + '开始Socket重连', tModul.IndexNo);
shutdown(skt, SD_BOTH);
Sleep(100);
raise Exception.Create('采集模块索引号:' + IntToStr(tModul.IndexNo) + '采集失败');
end
else
begin
UpdateListInfo(3, '采集完成');
OutMess('采集模块索引号:' + IntToStr(tModul.IndexNo) + '采集完成', tModul.IndexNo);
end;
mySleep(FQueryInterval);
end;
tModul.ActiveEvent;
end;
Sleep(10);
end;
if CollectFailCount >= 5 then //采集失败
begin
tmpStr := FName + ':采集失败,第' + IntToStr(CollectFailCount) + '次重新打开串口!';
OutMess(tmpStr, 'COM');
WriteSystemLog(tmpStr);
Break;
end;
Sleep(10);
end;
end;
finally
CloseSocket(skt);
end;
except on E: Exception do
WriteSystemLog(E.Message);
end;
end;
end;
相关推荐
UNIX网络编程
UNIX网络编程,学习的好书!
MySQL连接错误解决[代码]
文章详细描述了在连接MySQL服务器时遇到的ERROR 2005 (HY000): Unknown MySQL server host错误,并提供了解决方案。错误原因在于MySQL不支持在-h参数后直接使用IP:PORT的格式,正确的做法是使用-h IP -P PORT分开指定。此外,文章还提到了防火墙可能导致的连接问题,建议关闭或重新设置防火墙。通过具体的命令行示例,展示了错误和正确连接方式的对比,帮助读者快速理解和解决类似问题。
虚拟机连接本地MySQL[源码]
本文介绍了如何通过虚拟机连接本地MySQL数据库的步骤。首先使用`mysql -uroot -p123456`命令登录本地数据库,其中`root`为用户名,`123456`为密码。接着通过`GRANT ALL PRIVILEGES`命令授权远程登录账号访问权限,其中`*.*`表示授权所有数据库,`test.*`表示仅授权test数据库。远程登录账号、主机IP及密码需在命令中指定。此方法适用于需要从虚拟机访问本地MySQL数据库的场景。
SQL数据库校选课作业
1、SQL SERVER服务器的网库配置为TCP/IP socket,但使用1450作为端口。请问如何配置网库使访问成功: A、 At the server use the Network utility to use port 1450 B、 At the server use the Client utility to use port 1450 C、 At the Client configure the Client utility to use port 1450 2、 NT的SQLGROUP的成员连接SQL不能成功,经检查其default Net-Library是Named Pipes.最可能的原因是: A、 用户计算机上没有配置有效的ODBC DSN For SQL Server. B、 用户计算机没有同SQL Server.计算机建立可信连接 C、 SQL Server.数据库文件没有共享到网络上 D、 Windows NT的Guest用户被禁用 3、 你用QQL的身份安装了SQL2000,两个星期后,SQL Server.不能启动,最可能的原因是: A、 QQL没有管理员权限 B、 QQL的密码过期 C、 机器没有安装网卡 D、 以上都不对
Rose_Mirror_HA_3.2_forwindows的安装维护手册
Rose_Mirror_HA_3.2_forwindows的安装维护手册,详细步骤图文版。


网络通信/分布式开发
