訊息標頭檔案messageheader.hpp
#ifndef _messageheader_hpp_
#define _messageheader_hpp_
enum cmd ;
// 訊息頭
struct dataheader ;
struct login :public dataheader
char username[32];
char password[32];
};struct loginresult : public dataheader
int result;
};struct logout :public dataheader
char username[32];
};struct logoutresult :public dataheader
int result;
};struct newuserjoin :public dataheader
int sock;
};#endif
主函式如下
#include "easytcpserver.hpp"
int main()
server.close();
printf("已退出。\n");
return 0;
}
初始化函式實現
// 初始化
void initsocket()
_sock = socket(af_inet, sock_stream, 0);
if (invalid_socket == _sock)
printf("錯誤,建立socket<%d>失敗...\n",_sock);
else
printf("建立socket<%d>成功...\n",_sock);
}
繫結埠函式
// 繫結ip和埠號
socket bind(const char* ip, unsigned short port) ;
_sin.sin_family = af_inet;
_sin.sin_port = htons(9527);
#ifdef _win32
if (ip)
_sin.sin_addr.s_un.s_addr = inet_addr(ip);
else
_sin.sin_addr.s_un.s_addr = inaddr_any;
#else
if(ip)
_sin.sin_addr.s_addr = inet_addr(ip);
else
_sin.sin_addr.s_addr = inaddr_any;
#endif
int ret = bind(_sock, (sockaddr*)&_sin, sizeof(_sin));
if (socket_error == ret)
printf("錯誤,繫結網路埠<%d>失敗...\n", port);
else
printf("繫結埠<%d>成功...\n", port);
return _sock;
}
監聽函式
// 監聽埠號
int listen(int n)
檢測伺服器是伺服器是否在執行
// 判斷是否處在工作中
bool isrun()
通過select函式監聽客戶端連線,並接受客戶端通訊
bool onrun()
timeval t = ; // 時間引數,非阻塞模式
// int ret = select(maxsock + 1, &fdread, &fdwrite, &fdexp, &t);
if (ret < 0)
if (fd_isset(_sock, &fdread))
for (int n = (int)g_clients.size() - 1; n >= 0; n--) }}
}} return isrun();
}
accept函式
// 接受客戶端連線
socket accept() ;
int naddrlen = sizeof(sockaddr_in);
socket _csock = invalid_socket;
#ifdef _win32
_csock = accept(_sock, (sockaddr*)&clientaddr, &naddrlen);
#else
_csock = accept(_sock, (sockaddr*)&clientaddr, (socklen_t*)&naddrlen);
#endif
if (invalid_socket == _csock)
printf("接受到無效客戶端socket...\n");
// 像其他客戶端傳送通知
else
return _csock;
}
recv函式
// 接受資料,處理粘包,拆分包
int recvdata(socket _csock)
; int nlen = recv(_csock, (char*)&szrecv, sizeof(dataheader), 0);
dataheader* header = (dataheader*)szrecv;
if (nlen <= 0)
recv(_csock, szrecv + sizeof(dataheader), header->datalength - sizeof(dataheader), 0);
onnetmsg(_csock, header);
return 0;
}
處理訊息函式
// 響應網路訊息
virtual void onnetmsg(socket _csock, dataheader* header)
break;
case cmd_logout:
break;
default:
dataheader header = ;
send(_csock, (char*)&header, sizeof(header), 0);
} }
傳送資料
// 傳送資料
int senddata(socket _csock, dataheader* header)
像所有客戶端傳送資料
void senddatatoall(dataheader* header)
}
最後關閉套接字
// 關閉套接字
void close()
}
關於網路伺服器
假如我有數千萬甚至是上億的使用者資料,我想把使用者自增id和使用者名稱username放到快取裡。我的需求是,當要查詢使用者的資訊時,我想先從快取裡根據使用者名稱username獲取到使用者的id,然後再通過id在資料庫裡查詢使用者的資訊。我想當乙個使用者表達到上億的數量級別時,用自增id來查詢肯定...
網路伺服器宕機
1.伺服器程序終止 當伺服器程序終止時,伺服器傳送fin給客戶端,客戶端回以ack,客戶端進入close wait狀態,但還沒有結束連線。此時客戶端阻塞於fgets,客戶端繼續傳送buffer,伺服器傳送rst,客戶端readline返回0。而如果客戶端不理睬readline返回的rst,繼續wri...
linux網路伺服器
在本次中,學習了乙個簡單的基於tcp ip的伺服器 客戶端。在例子中,利用的是af inet域。在linux下,最常用就是af inet,af unix.af unix是linux檔案系統實現的本地要借字。後面的是可以用於包括英特網在內的tcp ip網路通訊的程式。下面來看乙個簡單的基於tcp ip...