本章節是用基本的linux/unix基本函式加上select呼叫編寫乙個完整的伺服器和客戶端例子,可在linux(ubuntu)和unix(freebsd)上執行,客戶端和服務端的功能如下:
客戶端從標準輸入讀入一行,傳送到服務端
服務端從網路讀取一行,然後輸出到客戶端
客戶端收到服務端的響應,輸出這一行到標準輸出
**如下:
#include**如下:#include /* basic system data types */
#include /* basic socket definitions */
#include /* sockaddr_in{} and other internet defns */
#include /* inet(3) functions */
#include /* select function*/
#include
#include
#include
#include
#define maxline 10240
void handle(int * clientsockfds, int maxfds, fd_set* prset, fd_set* pallset);
int main(int argc, char **ar**)
int opt = 1;
if (setsockopt(listenfd, sol_socket, so_reuseaddr, &opt, sizeof(opt)) < 0)
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = af_inet;
servaddr.sin_addr.s_addr = htonl(inaddr_any);
servaddr.sin_port = htons(servport);
if(bind(listenfd, (struct sockaddr*)&servaddr, socklen) == -1)
if (listen(listenfd, listenq) < 0)
int i = 0;
for (i = 0; i< fd_setsize; i++)
clientsockfds[i] = -1;
fd_zero(&allset);
fd_set(listenfd, &allset);
maxfd = listenfd;
printf("echo server use select startup, listen on port %d\n", servport);
printf("max connection: %d\n", fd_setsize);
for ( ; ; )
if (fd_isset(listenfd, &rset))
sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
printf(buf, "");
for (i = 0; i< fd_setsize; i++)
}if (i == fd_setsize)
if (connfd > maxfd)
maxfd = connfd;
fd_set(connfd, &allset);
if (--nready <= 0)
continue;
}handle(clientsockfds, maxfd, &rset, &allset);}}
void handle(int * clientsockfds, int maxfds, fd_set* prset, fd_set* pallset)
if (nread == 0)
write(clientsockfds[i], buf, nread);//響應客戶端 有可能失敗,暫不處理}}
}}
#include編譯和啟動服務端#include /* basic system data types */
#include /* basic socket definitions */
#include /* sockaddr_in{} and other internet defns */
#include /* inet(3) functions */
#include /* select function*/
#include
#include
#include
#include
#define maxline 10240
#define max(a,b) ((a) > (b) ? (a) : (b))
//typedef struct sockaddr sa;
void handle(int sockfd);
int main(int argc, char **ar**)
if (argc == 3)
if (argc > 3)
connfd = socket(af_inet, sock_stream, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = af_inet;
servaddr.sin_port = htons(servport);
inet_pton(af_inet, servinetaddr, &servaddr.sin_addr);
if (connect(connfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
printf("welcome to selectechoclient\n");
handle(connfd); /* do it all */
close(connfd);
printf("exit\n");
exit(0);
}void handle(int connfd)
if (fd_isset(connfd, &rset))
else if (nread == -1)
else
}if (fd_isset(fileno(fp), &rset))
else }}
}
gcc selectechoserver.c -o selectechoserver編譯和啟動客戶端
gcc selectechoclient.c -o selectechoclient
unix下網路程式設計之I O復用(二)
select函式 該函式允許程序指示核心等待多個事件中的任何乙個發生,並僅在有乙個或是多個事件發生或經歷一段指定的時間後才喚醒它。我們呼叫select告知核心對哪些描述字 就讀 寫或異常條件 感興趣以及等待多長時間。我們感興趣的描述字不侷限於套介面,任何描述字都可以使用select來測試。selec...
unix下網路程式設計之I O復用(二)
select函式 該函式允許程序指示核心等待多個事件中的任何乙個發生,並僅在有乙個或是多個事件發生或經歷一段指定的時間後才喚醒它。我們呼叫select告知核心對哪些描述字 就讀 寫或異常條件 感興趣以及等待多長時間。我們感興趣的描述字不侷限於套介面,任何描述字都可以使用select來測試。selec...
UNIX網路程式設計6 IO復用
i o多路復用是指核心一旦發現程序指定的乙個或者多個i o條件準備就緒,它就通知該程序。i o復用適用於以下場合 當客戶處理多個描述符 一般是互動式輸入或網路套接字 必須適用i o復用 套接字是乙個抽象出來的概念,本質上也是乙個檔案描述符 當乙個客戶處理多個套接字時,這種情況很少見,但也可能出現 當...