linuxtcp斷開
A. linux系統下的c語言的網路socket的編程,作為client端去連接伺服器段,為什麼之間會突然斷開!求高手指點!
在出錯函數(socket)後面用printf("%m\n");列印出來可以知道出錯的原因
%m表示errno和strerror(errno)
或者不怕麻煩的話添加頭文件<error.h>
然後還是在出錯的函數socket()後面添加列印信息printf("%d|%s\n", error, strerror(errno));
error表示該函數的出錯碼,後面的表示英文解釋,具體的可以在linux下用慢查找
雖然這個辦法笨了點。但是我只會這種方法....
你有抓包看了嗎 linux下用tcpmp -w抓到本地來看 本地用wireshark抓 一抓包啥東西都清清楚楚
B. linux下有系統tcp連接超時時間么
可以作為TCP連接的典範:
boolCRemoteLink::Connect()
{
OnDisconnected();//如果已經連接,則斷開
if(!m_bUseProxy)
{
m_iConnStatus=SS_CONNECTING;//正在連接狀態
GNTRACE("開始連接到遠程伺服器[%s][%ld]... ",m_strip.c_str(),m_port);
//建立套接字,准備連接到伺服器
m_socket=::socket(AF_INET,SOCK_STREAM,0);
if(socket<0){
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CREATE,MSG_SE_CREATE);
returnfalse;
}
//設為非同步操作方式
unsignedlongon=1;
if(::ioctlsocket(m_socket,FIONBIO,&on)<0){
::closesocket(m_socket);
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CREATE,MSG_SE_CREATE);
returnfalse;
}
sockaddr_inaddr;
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(m_strip.c_str());
addr.sin_port=htons(m_port);
intrt;
rt=::connect(m_socket,(sockaddr*)&addr,sizeof(addr));
if(rt==0){
OnConnected();
returntrue;
}
//==================================================================
timevalto;
//首先建立連接
fd_setwfds;
fd_setefds;
FD_ZERO(&wfds);
FD_ZERO(&efds);
//testshutdowneventeach100ms.
to.tv_sec=0;
//CONNECT_TIMEOUT;
to.tv_usec=100000;
intit=0;
while(!m_meShutdown.Wait(0)&&!m_meConnStop.Wait(0))
{
FD_SET(m_socket,&wfds);
FD_SET(m_socket,&efds);
intn=select(m_socket+1,NULL,&wfds,&efds,&to);
if(n>0){
if(FD_ISSET(m_socket,&wfds))
{
OnConnected();
returntrue;
}
else
{
//interr=::WSAGetLastError();
//constchar*msg=GetLastErrorMessage(err);
GNTRACE("CRemoteLink::Connect:connectionattemptfailed! ");
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CONN,MSG_SE_CONN);
break;
}
}elseif(n<0){//SelectError
interr=::WSAGetLastError();
constchar*msg=GetLastErrorMessage(err);
GNTRACE("CRemoteLink::Connect:SelectError.[%d]-%s ",err,msg);
if(m_pCallBack)
m_pCallBack->OnSocketError(err,msg);
break;
}
else
{
it+=100;
if(it>30000)//連接超時--(30S)
{
GNTRACE("CRemoteLink::Connect:Timeout. ");
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_TIMEOUT,MSG_SE_TIMEOUT);
break;
}
}
}
if(m_meConnStop.Wait(0))
{
GNTRACE("連接過程進行時被取消。 ");
}
}
else
{
//通過代理伺服器連接
C. Linux中TCP通信中 send函數 如何判斷 何時斷開連接了
1 確認鏈路是否連通狀態,最好加心跳機制, 如果一定時間沒有收到心跳包,或者沒有回復心跳
就應認為此鏈路已經壞掉了,需要關閉,重新連接!
2 至於發送數據,應該檢查對應的api的返回值,是否已經成功發送或者接受定長數據!
沒有完成應該重新發送或者接受
3 網路數據問題,可以用抓包工具直接抓包看數據,可以看的比較透徹
工具 Linux下用tcpmp,windows用wirekshark
D. linux中tcp連接斷開重蓮時伺服器應該怎麼處理
斷開重連,還是需要重新建立tcp三次握手,建立連接。
E. linux 操作系統 關閉非必要的TCP和UDP埠
Linux下面沒有什麼直接開啟或者關閉埠的命令,因為若僅僅只是開啟了埠而不把它與進程相聯系的話,埠的開啟與關閉就顯得毫無意義了(開了埠卻沒有程序處理進來的數據)。也就是說,Linux裡面埠的活動與進程是緊密相連的,如果想要關閉某個埠,那麼只要殺掉它對應的進程就可以了。
例如要關閉22號埠:
$ netstat -anp | grep :22
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1666/sshd
# -a 顯示所有活動的TCP連接,以及正在監聽的TCP和UDP埠
# -n 以數字形式表示地址和埠號,不試圖去解析其名稱(number)
# -p 列出與埠監聽或連接相關的進程(有個地方需要注意,下面會提到)(pid)
知道了22號埠對應的進程ID 1666,只要:
$ kill 1666
即可。
其中「-p」選項需要注意一個許可權的問題,如果在普通用戶登錄的shell裡面執行netstat命令,那麼只能列出擁有該普通用戶許可權的相關進程,如果想要看到所有的埠情況,最好還是切到root。
附帶幾個netstat常用選項用法:
$ netstat -tn # 列出所有TCP協議的連接狀態
# -t 只顯示與TCP協議相關的連接和埠監聽狀態,注意和-a有區別(tcp)
$ netstat -tuln # 列出所有inet地址類的埠監聽狀態
F. 檢查tcp 有沒有斷開 linux
client/server端recv:
①對端close(fd)檢測(超時檢測):recv 返回0,說明緩存區數據被讀完,實測兩種情況,對端沒有再發數據,對端fd被關閉了。
通過select超時來檢測,當超時如2s,我們認為對端連接斷開,應關閉本地的fd。
②網線斷開/斷電關機檢測(超時檢測):recv 返回-1,errno == EAGAIN,意為「沒有可讀寫數據,緩沖區無數據」。
所以此時需要select超時檢測,若超時,要麼對端沒有再發數據,要麼對端的網線斷了或者直接斷電了。
超過我們判定為對端不在線,關閉本地的fd。
G. linux tcp通信正常斷開和異常斷開分別該如何處理不用心跳機制
TCP 是面向連接的,自己有機制保證數據傳輸
TIMEOUT 不用自己去處理吧
H. linux在子進程中,client與server進行socket通信,客戶端socket斷開後不能與server連接,求高手指點
在不間斷的建立連接過程中,每一次的連接斷開會經過TCP狀態的time_wait狀態,這個狀態的作用就是延遲一段時間,然後保證下一次連接的不會被當成上一次的連接。所以第二次的連接建立時如果沒有經過一段時間第二次的連接會失敗,報錯會顯示address in use這兒就是time_wait狀態。你如果是在不同主機上進行不間斷的連接肯定會出現上面的報錯。
I. LINUX C 進行TCP網路連接,怎樣設置連接超時時間
如果你確定,真的不需要等這么久,或者用戶希望可以隨時中上連接過程,那麼一般是用 非阻塞模式來做的. 看看我的這段連接代碼(節選),可以作為TCP連接的典範:
bool CRemoteLink::Connect()
{
OnDisconnected(); // 如果已經連接,則斷開
if(!m_bUseProxy)
{
m_iConnStatus = SS_CONNECTING; // 正在連接狀態
GNTRACE ("開始連接到遠程伺服器[%s][%ld]...\n", m_strip.c_str(), m_port);
// 建立套接字, 准備連接到伺服器
m_socket = ::socket(AF_INET, SOCK_STREAM, 0);
if (socket < 0) {
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CREATE, MSG_SE_CREATE);
return false;
}
// 設為非同步操作方式
unsigned long on = 1;
if (::ioctlsocket(m_socket, FIONBIO, &on) < 0) {
::closesocket(m_socket);
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CREATE, MSG_SE_CREATE);
return false;
}
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(m_strip.c_str());
addr.sin_port = htons(m_port);
int rt;
rt = ::connect(m_socket, (sockaddr *) &addr, sizeof(addr));
if (rt == 0) {
OnConnected();
return true;
}
// ==================================================================
timeval to;
// 首先建立連接
fd_set wfds;
fd_set efds;
FD_ZERO(&wfds);
FD_ZERO(&efds);
// test shutdown event each 100ms.
to.tv_sec = 0;
// CONNECT_TIMEOUT;
to.tv_usec = 100000;
int it = 0;
while(!m_meShutdown.Wait(0) && !m_meConnStop.Wait(0))
{
FD_SET(m_socket, &wfds);
FD_SET(m_socket, &efds);
int n = select(m_socket + 1, NULL, &wfds, &efds, &to);
if (n > 0) {
if(FD_ISSET(m_socket, &wfds))
{
OnConnected();
return true;
}
else
{
//int err = ::WSAGetLastError();
//const char* msg = GetLastErrorMessage(err);
GNTRACE ("CRemoteLink::Connect : connection attempt failed!\n");
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CONN, MSG_SE_CONN);
break;
}
} else if (n < 0) { // Select Error
int err = ::WSAGetLastError();
const char* msg = GetLastErrorMessage(err);
GNTRACE ("CRemoteLink::Connect : Select Error.[%d] - %s\n", err, msg);
if(m_pCallBack)
m_pCallBack->OnSocketError(err, msg);
break;
}
else
{
it += 100;
if(it > 30000) // 連接超時 -- (30S)
{
GNTRACE ("CRemoteLink::Connect : Time out.\n");
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_TIMEOUT, MSG_SE_TIMEOUT);
break;
}
}
}
if(m_meConnStop.Wait(0))
{
GNTRACE("連接過程進行時被取消。\n");
}
}
else
{
// 通過代理伺服器連接
J. 關於linux系統下TCP通信 伺服器read函數一直讀取數據卻什麼都讀不到的問題
採用多線程編程,主進程負責等待連接到來,收到連接請求後父進程派生一個線程去處理該通信過程,通信處理交給該線程,父進程繼續循環等待連接請求。通信結束,該線程結束。
當然也可以採用信號觸發方式,當連接請求到來時,觸發父進程派生一個線程去處理該請求。