這裡我們為了讓客戶端有時間去處理其它業務邏輯,因此我們需要在客戶端也引入select模型。
#define win32_lean_and_mean
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
enum cmd
;struct dataheader
;//datapackage
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 scok;};
intprocessor
(socket _csock)
;// 5 接收客戶端資料
int nlen =
recv
(_csock, szrecv,
sizeof
(dataheader),0
);dataheader* header =
(dataheader*
)szrecv;
if(nlen <=0)
switch
(header->cmd)
break
;case cmd_logout_result:
break
;case cmd_new_user_join:
break;}
}int
main()
else
// 2 連線伺服器 connect
sockaddr_in _sin =
; _sin.sin_family = af_inet;
_sin.sin_port =
htons
(4567);
_sin.sin_addr.s_un.s_addr =
inet_addr
("127.0.0.1");
int ret =
connect
(_sock,
(sockaddr*
)&_sin,
sizeof
(sockaddr_in));
if(socket_error == ret)
else
while
(true)
;int ret =
select
(_sock,
&fdreads,0,
0,&t);
if(ret <0)
if(fd_isset
(_sock,
&fdreads))}
printf
("空閒時間處理其它業務..\n");
login login;
strcpy
(login.username,
"lyd");
strcpy
(login.password,
"lyd");
send
(_sock,
(const
char*)
&login,
sizeof
(login),0
);//sleep(1000);
}// 7 關閉套節字closesocket
closesocket
(_sock)
;//清除windows socket環境
wsacleanup()
;printf
("已退出。\n");
getchar()
;return0;
}
服務端的**做出微小改動:
#define win32_lean_and_mean
#define _winsock_deprecated_no_warnings
#include
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
enum cmd
;struct dataheader
;//datapackage
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 scok;};
std:
:vector g_clients;
intprocessor
(socket _csock)
;// 5 接收客戶端資料
int nlen =
recv
(_csock, szrecv,
sizeof
(dataheader),0
);dataheader* header =
(dataheader*
)szrecv;
if(nlen <=0)
switch
(header->cmd)
break
;case cmd_logout:
break
;default:;
send
(_csock,
(char*)
&header,
sizeof
(header),0
);}break;}
}int
main()
; _sin.sin_family = af_inet;
_sin.sin_port =
htons
(4567);
//host to net unsigned short
_sin.sin_addr.s_un.s_addr = inaddr_any;
//inet_addr("127.0.0.1");
if(socket_error ==
bind
(_sock,
(sockaddr*
)&_sin,
sizeof
(_sin)))
else
// 3 listen 監聽網路埠
if(socket_error ==
listen
(_sock,5)
)else
while
(true)
///nfds 是乙個整數值 是指fd_set集合中所有描述符(socket)的範圍,而不是數量
///既是所有檔案描述符最大值+1 在windows中這個引數可以寫0
timeval t =
;int ret =
select
(_sock +1,
&fdread,
&fdwrite,
&fdexp,
&t);
if(ret <0)
//判斷描述符(socket)是否在集合中 if(
fd_isset
(_sock,
&fdread));
int naddrlen =
sizeof
(sockaddr_in)
; socket _csock = invalid_socket;
_csock =
accept
(_sock,
(sockaddr*
)&clientaddr,
&naddrlen);if
(invalid_socket == _csock)
else
g_clients.
push_back
(_csock)
;printf
("新客戶端加入:socket = %d,ip = %s \n",(
int)_csock,
inet_ntoa
(clientaddr.sin_addr));
}}for(size_t n =
0; n < fdread.fd_count; n++)}
}printf
("空閒時間處理其它業務..\n");
}for
(size_t n = g_clients.
size()
-1; n >=
0; n--
)// 8 關閉套節字closesocket
closesocket
(_sock)
;//------------
//清除windows socket環境
wsacleanup()
;printf
("已退出。\n");
getchar()
;return0;
}
服務端使用select模型處理多客戶端
包頭 struct dataheader 包體 struct login public dataheader char username 32 char password 32 struct loginresult public dataheader int result struct logout...
基於select模型的udp客戶端實現超時機制
參考 多路選擇i o select模型 其思想在於使用乙個集合,該集合中包含需要進行讀寫的fd,通過輪詢這個集合,直到有乙個fd可讀寫,才返回。與阻塞i o不同的是,阻塞i o僅使用了一次系統呼叫,就是對fd的讀寫,如果沒有fd處於就緒狀態,則程序一直阻塞,而多路選擇i o使用了兩次系統呼叫,第一次...
Mac OS 公升級svn客戶端
mac os 10.9 系統帶的預設svn客戶端是1.7.x版本的。在使用checkout來的1.8版本的工程下 svn info 提示需要公升級客戶端 安裝完成,最後一步提示新增svn位址到path變數中,然後在終端執行以下命令 cd vi bash profile 在 bash profile檔...