前言
之前有看到用很幽默的方式講解Windows的socket IO模型,借用這個故事,講解下linux的socket IO模型;
老陳有一個在外地工作的女兒,不能經(jīng)常回來,老陳和她通過信件聯(lián)系。
他們的信會被郵遞員投遞到他們小區(qū)門口的收發(fā)室里。這和Socket模型非常類似。下面就以老陳接收信件為例講解linux的 Socket I/O模型。
一、同步阻塞模型
老陳的女兒第一次去外地工作,送走她之后,老陳非常的掛心她安全到達沒有;
于是老陳什么也不干,一直在小區(qū)門口收發(fā)室里等著她女兒的報平安的信到;這就是linux的同步阻塞模式;
在這個模式中,用戶空間的應(yīng)用程序執(zhí)行一個系統(tǒng)調(diào)用,并阻塞,直到系統(tǒng)調(diào)用完成為止(數(shù)據(jù)傳輸完成或發(fā)生錯誤)。
Socket設(shè)置為阻塞模式,當(dāng)socket不能立即完成I/O操作時,進程或線程進入等待狀態(tài),直到操作完成。
如圖1所示:

/* * /brief * tcp client */#include #include #include #include #include #define SERVPORT 8080#define MAXDATASIZE 100int main(int argc, char *argv[]){ int sockfd, recvbytes; char rcv_buf[MAXDATASIZE]; /*./client 127.0.0.1 hello */ char snd_buf[MAXDATASIZE]; struct hostent *host; /* struct hostent * { * char *h_name; // general hostname * char **h_aliases; // hostname's alias * int h_addrtype; // AF_INET * int h_length; * char **h_addr_list; * }; */ struct sockaddr_in server_addr; if (argc < 3) { printf("Usage:%s [ip address] [any string]/n", argv[0]); return 1; } *snd_buf = '/0'; strcat(snd_buf, argv[2]); if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket:"); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVPORT); inet_pton(AF_INET, argv[1], &server_addr.sin_addr); memset(&(server_addr.sin_zero), 0, 8); /* create the connection by socket * means that connect "sockfd" to "server_addr" * 同步阻塞模式 */ if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } /* 同步阻塞模式 */ if (send(sockfd, snd_buf, sizeof(snd_buf), 0) == -1) { perror("send:"); exit(1); } printf("send:%s/n", snd_buf); /* 同步阻塞模式 */ if ((recvbytes = recv(sockfd, rcv_buf, MAXDATASIZE, 0)) == -1) { perror("recv:"); exit(1); } rcv_buf[recvbytes] = '/0'; printf("recv:%s/n", rcv_buf); close(sockfd); return 0;} 顯然,代碼中的connect, send, recv都是同步阻塞工作模式,
在結(jié)果沒有返回時,程序什么也不做。
這種模型非常經(jīng)典,也被廣泛使用。優(yōu)勢在于非常簡單,等待的過程中占用的系統(tǒng)資源微乎其微,程序調(diào)用返回時,必定可以拿到數(shù)據(jù);但簡單也帶來一些缺點,程序在數(shù)據(jù)到來并準(zhǔn)備好以前,不能進行其他操作,需要有一個線程專門用于等待,這種代價對于需要處理大量連接的服務(wù)器而言,是很難接受的。
二、同步非阻塞模型
收到平安信后,老陳稍稍放心了,就不再一直在收發(fā)室前等信,而是每隔一段時間就去收發(fā)室檢查信箱,這樣,老陳也能在間隔時間內(nèi)休息一會,或喝杯荼,看會電視,做點別的事情,這就是同步非阻塞模型。
新聞熱點
疑難解答