select函式原型:
int select(int maxfdp, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)
這裡用到兩個結構體fd_set和timeval。fd_set可以理解為乙個集合,時存放檔案描述符的(想stdout_fileno、stdin_fileno以及socket函式的返回的檔案的控制代碼)
select引數列表:
maxfd:指集合中所有檔案描述負的範圍,即所有檔案描述符的最大值加1
readfds:監視可讀的檔案描述符的集合,即readfds中有檔案可讀,select返回乙個大於0的值,在根據timeout判斷是否超時,超時返回0,發生錯誤返回負數。
writefds:監視可讀檔案描述集合
errorfds:監視檔案描述符異常的集合
timeout:設定超時時間
fd_set相關的函式:
fd_set set; //初始化
fd_zero(&set); //清空
fd_set(fd, &set); //新增檔案描述符到set
fd_clr(fd, &set); //將fd從set中刪除
fd_isset(fd, &set); //檢查set中fd是否可讀
下面使用select模型實現乙個簡單的server、client
server.cpp
#
include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define
defaut_port
6666
intmain()
printf
("socket ok\n");
my_addr.sin_family = af_inet;
my_addr.sin_port =
htons
(defaut_port)
;//將主機位元組序的監聽埠轉換成網路位元組序
my_addr.sin_addr.s_addr = inaddr_any;
//監聽來自所有網路的訊息
bzero(&
(my_addr.sin_zero),0
);//將需要監聽的socket:serverfd與本地主機繫結if(
bind
(serverfd,
(struct
sockaddr*)
&my_addr,
sizeof
(struct
sockaddr))
==-1)
printf
("bind ok\n");
if(listen
(serverfd, lisnum)==-
1)printf
("listen ok\n");
fd_set client_fdst;
//監控檔案描述符集合
int maxsock;
//監控檔案描述符中最大的檔案號
struct
timeval tv;
//超時返回時間
int client_sockfd[5]
;//存放存活的sockfd
bzero((
void
*)client_sockfd,
sizeof
(client_sockfd));
int conn_amount =0;
//記錄描述符數量
maxsock = serverfd;
char buffer[
1024];
int ret =0;
while(1
)}ret =
select
(maxsock +1,
&client_fdst,
null
,null
,&tv);if
(ret <0)
else
if(ret ==0)
//輪詢所有的檔案描述符
for(
int index =
0; index < conn_amount; index++
)else}}
//檢查是否有新鏈結,如果有新連線,新增到client_sockfd集合中if(
fd_isset
(serverfd,
&client_fdst)
)//把鏈結新增到集合中
if(conn_amount <5)
printf
("recv : %s\n"
, buffer);if
(sock_client > maxsock)
else}}
}for
(int index =
0; index <
5; index++)}
close
(serverfd)
;return0;
}
client.cpp
#
include
#include
#include
#include
#include
#include
#include
#include
#include
#define
defaut_port
6666
intmain
(int argc,
char
*ar**)
client.sin_family = af_inet;
client.sin_port =
htons
(defaut_port)
; client.sin_addr.s_addr =
inet_addr
(ar**[1]
);connfd =
socket
(af_inet, sock_stream,0)
;if(connfd <0)
if(connect
(connfd,
(struct
sockaddr*)
&client,
sizeof
(struct
sockaddr))
<0)
char buffer[
1024];
bzero
(buffer,
sizeof
(buffer));
recv
(connfd,
&buffer,
sizeof
(buffer),0
);printf
("recv : %s\n"
, buffer)
;bzero
(buffer,
sizeof
(buffer));
strcpy
(buffer,
"this is client!\n");
send
(connfd, buffer,
sizeof
(buffer),0
);while(1
)close
(connfd)
;return0;
}
linux中網路程式設計I O模型 poll
poll函式原型 int poll struct pollfd fds,unsigned int nfds,int timeout struct pollfd poll引數列表 events和reevents值列表 事件分類 事件 意義合法事件 pollin 有可讀資料 合法事件 pollrdnor...
Linux網路程式設計之IO模型
同步是指乙個任務的完成需要依賴另外乙個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成。非同步是指不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工作,依賴的任務也立即執行,只要自己完成了整個任務就算完成了,非同步一般使用狀態 通知和 阻塞是指呼叫結果返回之前,當前執行緒會被掛起,...
《網路程式設計》I O 模型
在分析 i o 模型之前,首先了解 同步 i o 和 非同步 i o 的基本概念 同步 i o 程序呼叫 i o 操作函式時,在 i o 操作函式返回之前,該程序會被掛起 即阻塞 直到 i o 操作完成後返回 非同步 i o 程序呼叫 i o 操作函式時,在 i o 操作函式返回之前,該程序不會被掛...