1. 程式人生 > >基於TCP的socket程式設計網路掉線重連

基於TCP的socket程式設計網路掉線重連

基於TCP的socket程式設計
sockets(套接字)程式設計有三種,流式套接字(SOCK_STREAM),資料報套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基於TCP的socket程式設計是採用的流式套接字。
正在裝載資料…
在這個程式中,將兩個工程新增到一個工作區。要連結一個ws2_32.lib的庫檔案。
伺服器端程式設計的步驟:
1:載入套接字型檔,建立套接字(WSAStartup()/socket());
2:繫結套接字到一個IP地址和一個埠上(bind());
3:將套接字設定為監聽模式等待連線請求(listen());
4:請求到來後,接受連線請求,返回一個新的對應於此次連線的套接字(accept());

5:用返回的套接字和客戶端進行通訊(send()/recv());
6:返回,等待另一連線請求;
7:關閉套接字,關閉載入的套接字型檔(closesocket()/WSACleanup())。
伺服器端程式碼如下:
#include <stdio.h>
#include <Winsock2.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return; 
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[50];
sprintf(sendBuf,"Welcome s to here!",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf) 1,0);
char recvBuf[50];
recv(sockConn,recvBuf,50,0);
printf("s\n",recvBuf);
closesocket(sockConn);
}
}

客戶端程式設計的步驟:
1:載入套接字型檔,建立套接字(WSAStartup()/socket());
2:向伺服器發出連線請求(connect());
3:和伺服器端進行通訊(send()/recv());
4:關閉套接字,關閉載入的套接字型檔(closesocket()/WSACleanup())。
客戶端的程式碼如下:
#include <stdio.h>
#include <Winsock2.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return; 
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[50];
recv(sockClient,recvBuf,50,0);
printf("s\n",recvBuf);
send(sockClient,"hello",strlen("hello") 1,0);
closesocket(sockClient);
WSACleanup();
}
請問: 
    我的client,server都是同步,想用tcp協議提供的heartbeat機制檢測網路連線是否中斷。網上找來如下程式碼,請問如和使用?是在client,server的socket建立好後都要加如下程式碼還是隻需要一方加上就行了?另外通過如下程式碼我recv受到的資料包應該是什麼內容?下面程式碼需要寫在一個執行緒中不停的判斷WSAIoctl返回值嗎?請高人指點。 
//設定KeepAlive   
BOOL       bKeepAlive       =       TRUE;   
nRet       =       ::setsockopt(m_sockDesc,       SOL_SOCKET,       SO_KEEPALIVE,       (char*)&bKeepAlive,       sizeof(bKeepAlive));   
if       (nRet       !=0)   
{   
sprintf(m_pszError,       "Winsock       error       :       %s       (Error       Code       %d)\n   ",       "Socket       SetOpt       failed   ",       WSAGetLastError());   
return       FALSE;   
}   
//設定KeepAlive檢測時間和次數   
TCP_KEEPALIVE       inKeepAlive       =       {0};       //輸入引數   
unsigned       long       ulInLen       =       sizeof(TCP_KEEPALIVE);           

TCP_KEEPALIVE       outKeepAlive       =       {0};       //輸出引數   
unsigned       long       ulOutLen       =       sizeof(TCP_KEEPALIVE);           

unsigned       long       ulBytesReturn       =       0;   
//設定socket的keep       alive為10秒,並且傳送次數為3次   
inKeepAlive.onoff       =       1;       
inKeepAlive.keepaliveinterval       =       10000;       //兩次KeepAlive探測間的時間間隔   
inKeepAlive.keepalivetime       =       3;       //開始首次KeepAlive探測前的TCP空閉時間   
nRet       =       WSAIoctl(m_sockDesc,       
SIO_KEEPALIVE_VALS,   
(LPVOID)&inKeepAlive,   
ulInLen,   
(LPVOID)&outKeepAlive,   
ulOutLen,   
&ulBytesReturn,   
NULL,   
NULL);   
if(SOCKET_ERROR       ==       nRet)   
{   
sprintf(m_pszError,       "Winsock       error       :       %s       (Error       Code       %d)\n   ",       "Nonblocking       socket       call       error   ",       WSAGetLastError());   
return       FALSE;   
}   
心跳是邏輯應用層的東西,需要自己實現,一般為自定義,當socket空閒時,傳送心跳包,報檔案格式自定義! 
我現在也遇到心跳檢測的問題.網上查沒查到,感覺大多比較籠統,就自己做吧. 
自己根據需要想了一下.客戶端發自定義的心跳包,伺服器端接收到心跳包向客戶端返回個東西 
然後客戶端再處理.實現上是可以的. 
因為水平有限,還是想學習一下標準的做法 
心跳檢測需要以下步驟: 
1       客戶端每隔一個時間間隔發生一個探測包給伺服器 
2       客戶端發包時啟動一個超時定時器 
3       伺服器端接收到檢測包,應該回應一個包 
4       如果客戶機收到伺服器的應答包,則說明伺服器正常,刪除超時定時器 
5       如果客戶端的超時定時器超時,請問: 
    我的client,server都是同步,想用tcp協議提供的heartbeat機制檢測網路連線是否中斷。網上找來如下程式碼,請問如和使用?是在client,server的socket建立好後都要加如下程式碼還是隻需要一方加上就行了?另外通過如下程式碼我recv受到的資料包應該是什麼內容?下面程式碼需要寫在一個執行緒中不停的判斷WSAIoctl返回值嗎?請高人指點。 
//設定KeepAlive   
BOOL       bKeepAlive       =       TRUE;   
nRet       =       ::setsockopt(m_sockDesc,       SOL_SOCKET,       SO_KEEPALIVE,       (char*)&bKeepAlive,       sizeof(bKeepAlive));   
if       (nRet       !=0)   
{   
sprintf(m_pszError,       "Winsock       error       :       %s       (Error       Code       %d)\n   ",       "Socket       SetOpt       failed   ",       WSAGetLastError());   
return       FALSE;   
}   
//設定KeepAlive檢測時間和次數   
TCP_KEEPALIVE       inKeepAlive       =       {0};       //輸入引數   
unsigned       long       ulInLen       =       sizeof(TCP_KEEPALIVE);       
TCP_KEEPALIVE       outKeepAlive       =       {0};       //輸出引數   
unsigned       long       ulOutLen       =       sizeof(TCP_KEEPALIVE);           
unsigned       long       ulBytesReturn       =       0;   
//設定socket的keep       alive為10秒,並且傳送次數為3次   
inKeepAlive.onoff       =       1;       
inKeepAlive.keepaliveinterval       =       10000;       //兩次KeepAlive探測間的時間間隔   
inKeepAlive.keepalivetime       =       3;       //開始首次KeepAlive探測前的TCP空閉時間   

nRet       =       WSAIoctl(m_sockDesc,       
SIO_KEEPALIVE_VALS,   
(LPVOID)&inKeepAlive,   
ulInLen,   
(LPVOID)&outKeepAlive,   
ulOutLen,   
&ulBytesReturn,   
NULL,   
NULL);   
if(SOCKET_ERROR       ==       nRet)   
{   
sprintf(m_pszError,       "Winsock       error       :       %s       (Error       Code       %d)\n   ",       "Nonblocking       socket       call       error   ",       WSAGetLastError());   
return       FALSE;   
}   

心跳檢測需要以下步驟: 
1       客戶端每隔一個時間間隔發生一個探測包給伺服器 
2       客戶端發包時啟動一個超時定時器 
3       伺服器端接收到檢測包,應該回應一個包 
4       如果客戶機收到伺服器的應答包,則說明伺服器正常,刪除超時定時器 
5       如果客戶端的超時定時器超時,依然沒有收到應答包,則說明伺服器掛了 

依然沒有收到應答包,則說明伺服器掛了 
DWORD   NetSessionEnum(   LPSTR,   
DWORD,   
LPBYTE,   
DWORD,   
LPDWORD,   
LPDWORD   )   
引數1:   NULL表示列舉本機的網路連線   
引數2:   不詳.在列舉中是常量0x32.   
引數3:   存放資訊的緩衝區指標   
引數4:   緩衝區長度   
引數5:   指向返回連線個數   
引數6:   指向總共連線個數   
Top
在WINDOWS95&WINDOWS98下如何關閉網路連線     
   --------------------------------------------------------------------------------   
如果你有這個方面的問題請到C/C++去提問或發表你的意見        來源:論壇轉載無法確定出處,如有版權問題請與我們聯絡      在WINDOWS95&WINDOWS98下如何關閉網路連線   
一.問題提出:       每當你通過WINDOWS95或WINDOWS98訪問"網路上的芳鄰"時,系統自動的建立了兩   
臺機器之間的網路連線關係,但是在訪問結束後,並不自動的斷開網路連線,   
所以有時我們關閉WINDOWS系統時,會彈出一個對話方塊,詢問是否關閉網路連   
接,在回答"YES"後,才真正開始關閉計算機.   
程式設計師編制系統關閉程式時,就需要考慮這種情況,雖然SDK提供了關機的API:   
ExitWindowsEx()和ExitWindows(),但實際應用中我發現,在指定FORCE關機時   
在特定情況下會出問題.所以,必須想辦法首先斷開網路連線.      
二.程式設計介面:      
WINDOWS95及WINDOWS98提供的這方面的網路程式設計介面在SVRAPI.DLL中,利用它   
我們可以列舉出當前網路連線狀態,控制或刪除網路連線.WINDOWS附件中的   
NETWATCH.EXE工具就是這樣實現的.   
也許您會問,NetAPI的詳細說明在開發工具的SDK文件中很詳細了,沒有必要在   
此演示.但是,在查尋了很多資料後,我不得不說:MSDN中有關NetAPI的部分說   

相關推薦

基於TCP的socket程式設計網路

基於TCP的socket程式設計 sockets(套接字)程式設計有三種,流式套接字(SOCK_STREAM),資料報套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基於TCP的socket程式設計是採用的流式套接字。 正在裝載資料… 在這個程式中,

使用netty進行客戶端網路程式設計及斷功能實現

       不管做哪個方向開發,都會有那麼一兩個牛B閃閃的庫,可以極大的方便開發,比如java網路程式設計中的netty庫。無論客戶端還是服務端網路程式設計,netty基本都是首選網路庫,健壯、高效、穩定,並且已經得到很多商業專案驗證。        當用netty進行客

Ubuntu14.04 Wifi 連線不穩定、問題(終極解決辦法)

Ubuntu14.04 Wifi 連線不穩定、上不了網、掉線問題(終極解決辦法) 這可能是我寫的最短的一篇部落格。 用Ubuntu系統的人知道,有線連線比較穩定;一般桌上型電腦不帶網絡卡,自己某寶購買的無線網絡卡插上去後能連線wifi,但是過一分鐘就掉線了,

Windows C語言 Socket程式設計 client端(客戶端)--斷

瞭解了最基礎的C語言客戶端的編寫流程,稍稍加以改動即可實現斷線重連。 當伺服器掉線時,客戶端會以固定的頻率不停的重連。 #include <stdio.h> #include <winsock2.h> #pragma comme

即時通訊判斷網路狀態和斷機制

本文借鑑csdn大神way的xmpp客戶端學習改造而來,不足之處希望大家多多指教!  1. 由於近半年來一直寫針對於tigase伺服器的即時通訊軟體的開發,框架的重構,對即時通訊的理解也較之前更進一步,在客戶端的IM開發中,最重要的除去通訊的建立,就是保持網路環境不斷更換時

手機客戶端弱網路下的斷處理

1、弱網路下的斷線重連   玩家在遊戲過程中,所處的網路環境是複雜多變的,可能是wifi的網路不穩定,或處在3G甚至2G的環境下等。在這些情況下,網路遊戲會由於網路或包量等原因而出現延遲,拉拽,甚至掉線等問題。對於這些問題,一方面要對程式的包量和通訊進行優化,從根本上減緩

nodejs中mysql斷

調試 狀態 pan var 參考 ble prot nec clas 之前寫了個小程序Node News,用到了MySQL數據庫,在本地測試均沒神馬問題。放上服務器運行一段時間後,偶然發現打開頁面的時候頁面一直處於等待狀態,直到Nginx返回超時錯誤。於是上服務器檢查了遍,

android 實現mqtt訊息推送,以及不停斷的問題解決

前段時間專案用到mqtt的訊息推送,整理一下程式碼,程式碼的原型是網上找的,具體哪個地址已經忘記了。 程式碼的實現是新建了一個MyMqttService,全部功能都在裡面實現,包括連伺服器,斷線重連,訂閱訊息,處理訊息,釋出訊息等基本操作。 首先新增依賴: dependencies { &

django的資料庫斷

django每次查詢都會被把連線關閉,想保持長連線方法如下: from django.core import signals from django.db import close_connection # 取消訊號關聯,實現資料庫長連線 signals.request

Android RxJava操作符的學習---功能性操作符--網路請求出錯(結合Retrofit)

1. 需求場景   2. 功能說明 功能需求說明     功能邏輯  例項說明 在本例子中:採用Get方法對 金山詞霸API 傳送網路請求 通過 斷開網路連線 模擬 網路異常錯誤(恢復網路即可

【UE4】 第12講 FSocket斷

(版權宣告,禁止轉載) 【第03講】 實現了FSocket的連網基礎功能,這一講實現一下 斷線重連 <如果資深前輩發現有理解錯誤,還請不吝指正> <1> 建立Socket,設定阻塞模式(預設創建出來的就是阻塞模式,不用設定)  

teamtalk socket斷問題的查詢

之前從teamtalk的核心庫裡面剝離出一個跨平臺網路庫,一開始用的好好的,可是在某些地方使用的時候總是出怪問題,有時候斷線重連就一直連不上,導致應用失聯,在實際使用場景中一直出問題,好不尷尬。 經過連三天的苦思冥想,除錯程式碼看輸出終於有些眉目了。 我是從以下幾個方面著手解決的,特此記錄一

ActiveMQ的斷機制

primary active 節點 語法 無限 機制 新的 bubuko 獲取 斷線重連機制是ActiveMQ的高可用性具體體現之一。ActiveMQ提供failover機制去實現斷線重連的高可用性,可以使得連接斷開之後,不斷的重試連接到一個或多個brokerURL。 默認

關於資料庫斷的一點點思考

最近在寫資料庫連結池,一個不可逃避的問題就是資料庫斷線重連。 查了很多資料,因為公司有很多專案用了 TP5 於是也去看了它的原始碼。 tp5的實現其實很簡單,配置了一些資料庫連線相關的錯誤資訊關鍵詞(句),然後在執行語句時 catch 異常資訊進行比對: // 伺服器斷線標識字元 p

Yii2實現mysql斷[轉載]

最近遇到“Yii2實現mysql斷線重連”問題,找了好久資料,最後找到這篇文件是說明了該情況的,感謝這位作者的分享,記錄下來,必備以後查閱。 原文連結:https://www.yiichina.com/topic/7296 Yii2實現資料庫斷線重連 一、前話 在工作中,有時候一

netty4.0 心跳檢測與斷操作

因為最近專案最近要用netty,服務端放在雲端,客戶端發在內網。那如何實現netty長連線和斷線重連呢(網路故障或者其他原因,客戶端要無限取重連服務端)。接下來我們看一下如何實現這個兩個功能呢。 服務端程式碼如下: package com.example.nettydem

mqtt協議 springboot2.0.4 mqttv3 釋出訂閱程式碼呼叫,mqtt斷

mqttv3 釋出訂閱程式碼呼叫 我用的是springboot2.0.4 直接上程式碼: pom.xml <dependency> <groupId>org.eclipse.paho</groupId>

iOS MQTT使用案例 (斷)

iOS MQTT使用案例 (斷線重連) 參考了 iOS MQTT—-MQTTClient實戰-看這篇的就夠了 大神寫的這篇 git: MQTT-Client-Framework 介紹啥的看百度,上面大神寫的就行了,直接上乾貨。 安裝: pod 'MQTTClient'

Node.js連線RabbitMQ,斷,動態繫結routing key

RabbitMQ官方提供的教程https://www.rabbitmq.com/tuto...,是基於回撥的。 下面將給出基於Promise式的寫法。並且實現動態的佇列繫結 初始化配置 const amqp = require('amqplib') // rabbitMQ地址 const {amqpA

WebSocket在服務端和客戶端通訊demo,支援心跳檢測+斷

一、為什麼需要 WebSocket? 初次接觸 WebSocket 的人,都會問同樣的問題:我們已經有了 HTTP 協議,為什麼還需要另一個協議?它能帶來什麼好處? 答案很簡單,因為 HTTP 協議有一個缺陷:通訊只能由客戶端發起。 舉例來說,我們想了解今天的天氣,只能是客戶端向伺服器發出