unix下網路程式設計之I O復用(五)

2021-09-07 18:07:22 字數 3365 閱讀 1878

本章節是用基本的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復用 套接字是乙個抽象出來的概念,本質上也是乙個檔案描述符 當乙個客戶處理多個套接字時,這種情況很少見,但也可能出現 當...