首先,如果使用select函數來做網絡通訊,即使不用多線程也是沒有問題的。
如果說妳在關閉監聽線程,我暫且理解妳想要結束服務了,那麽:
1。在合適的地方,將socket關閉。
2。select函數本身沒有什麽釋放的必要,之要在監聽線程做好各項釋放工作。
3。監聽線程返回壹個合適的狀態碼。
我上壹個我自己寫的,比較簡單,應該很好理解:
typedef?struct?_lbs_socket_object_st?lbs_netlib_object_t;
struct?_lbs_socket_object_st?{
/*?Real?socket?of?the?object?*/
SOCKET?sock;
struct?sockaddr_in?addr;
struct?sockaddr_in?udp_addr;
HANDLE?worker;
/*?Flag?shows?that?if?this?object?is?a?server?or?client?*/
lbs_bool_t?is_server;
lbs_bool_t?is_udp;
/*?Socket?type:?STREAM?or?DGRAM?*/
int?type;
/*?Working?method?flag?*/
int?flag;
/*
*?Server?Mode:?True?if?server?is?started. *?Client?Mode:?True?if?client?has?connected?to?server. */int?actived;
/*?Fields?below?are?used?for?server?*/
int?threads_expension_type;?//?Method?for?thread?pool
int?threads_cnt;?//?Count?of?threads?in?threads?pool
int?clients_cnt;?//?Count?of?clients?who?are?connected
lbs_sock_node_t*?client_head;
/*?Only?server?will?use?a?thread?pool?*/
lbs_thread_pool_handle_t?threadpool;
/*?Callback?functions?*/
read_callback?read_cb;
error_callback?error_cb;
int?error;
lbs_socket_object_t*?next;
lbs_socket_object_t*?prev;
};
unsigned?long?_stdcall?lbs_netlib_server_listen_thread(void*?param)
{
lbs_netlib_object_t*?server?=?(lbs_netlib_object_t*)param;
FD_SET?listen_fdset;
FD_SET?temp_fdset;
struct?timeval?tv?=?{5,?100};
int?rc;
/*?Check?for?parameters*/
if?(server?==?0)?{
/*?@@@?We?can?not?pass?this?error?to?anywhere.
*?@@@?Maybe?we?can?write?it?into?log?in?the?future. */return?1;
}
/*?Do?some?initializations?*/
FD_ZERO(&listen_fdset);
FD_ZERO(&temp_fdset);
FD_SET(server->sock,?&listen_fdset);
/*?Process?loop?*/
while?(1)?{
int?event_cnt;?//?Event?counts?set?by?'select'
temp_fdset?=?listen_fdset;
/*?whether?caller?wants?to?stop?server?*/
if?(server->actived?==?0)?{
goto?clean_up;
}
/*?Detect?events?*/
event_cnt?=?select(0,?&temp_fdset,?0,?0,?&tv);
if?(event_cnt?==?0)?continue;
if?(FD_ISSET(server->sock,?&temp_fdset))?{
int?size;
lbs_sock_node_t*?client;
client=?lbs_netlib_new_client_node();
if?(client?==?0)?{
/*?@@@?There?is?not?memory.?We?should?log?error?here?*/
continue;
}
size?=?sizeof(struct?sockaddr_in);
client->sock?=?accept(server->sock,?(struct?sockaddr*)&(client->addr),?&size);
if?(client->sock?==?-1){
/*?@@@?Socket?cannot?be?created.?Maybe?system?does?not
*?have?such?resources.?We?should?log?error?here.
*/
rc?=?GetLastError();
lbs_rwlock_unlock(server->obj_lock);
lbs_netlib_destroy_client_node(client,?0);
}?else?{
lbs_rwlock_unlock(server->obj_lock);
if?(!lbs_threadpool_push_task(server->threadpool,?client,?0))?{
server->clients_cnt++;
if?(server->error_cb)?{
server->error_cb((lbs_netlib_client_t)client,?0);
}
}
}?//?Exit?of?accept?result?checking
}?//?Exit?of?select?result?checking
}?//?Exit?of?loop
clean_up:
return?LBS_NETLIB_OK;
}