socket阻塞和非阻塞的區(qū)別是什么
出處:網(wǎng)絡(luò)整理 發(fā)布于:2025-06-10 17:08:46
Socket 的阻塞(Blocking)和非阻塞(NON-blocking)模式是網(wǎng)絡(luò)編程中兩種重要的 I/O 操作方式,主要區(qū)別在于程序在等待 I/O 操作完成時(shí)的行為。以下是它們的區(qū)別:
1. 阻塞模式(Blocking)
特點(diǎn)
調(diào)用會(huì)一直等待,直到操作完成或出錯(cuò)才返回。
線程/進(jìn)程會(huì)被掛起,無(wú)法執(zhí)行其他任務(wù),直到 I/O 操作結(jié)束。
適用于簡(jiǎn)單、同步的網(wǎng)絡(luò)通信,編程模型直觀。
常見(jiàn)阻塞操作
recv():如果沒(méi)有數(shù)據(jù)到達(dá),線程會(huì)一直阻塞,直到有數(shù)據(jù)。send():如果發(fā)送緩沖區(qū)滿(mǎn),線程會(huì)阻塞,直到數(shù)據(jù)被發(fā)送。accept():如果沒(méi)有新連接,線程會(huì)阻塞,直到有客戶(hù)端連接。connect():在 TCP 連接建立成功或失敗前,線程會(huì)阻塞。
示例(TCP 阻塞 recv)
c
char buffer[1024]; int bytes = recv(sockfd, buffer, sizeof(buffer), 0); // 阻塞,直到收到數(shù)據(jù)或出錯(cuò) printf("Received: %d bytes\n", bytes);如果沒(méi)有數(shù)據(jù)可讀,程序會(huì)卡在
recv()處,直到數(shù)據(jù)到達(dá)或連接關(guān)閉。
優(yōu)點(diǎn)
編程簡(jiǎn)單,邏輯清晰。
適合低并發(fā)、同步處理的場(chǎng)景。
缺點(diǎn)
并發(fā)能力差:每個(gè)連接需要一個(gè)線程/進(jìn)程,資源消耗大(C10K 問(wèn)題)。
響應(yīng)性差:如果一個(gè)連接阻塞,整個(gè)線程無(wú)法處理其他任務(wù)。
2. 非阻塞模式(Non-blocking)
特點(diǎn)
調(diào)用立即返回,無(wú)論操作是否完成。
線程不會(huì)被掛起,可以繼續(xù)執(zhí)行其他任務(wù)。
需要輪詢(xún)或事件驅(qū)動(dòng)(如
select/poll/epoll) 來(lái)檢查 I/O 狀態(tài)。適用于高并發(fā)、異步 I/O 場(chǎng)景(如 Web 服務(wù)器、游戲服務(wù)器)。
如何設(shè)置非阻塞 Socket?
在 Linux 下:
c
int flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); // 設(shè)置為非阻塞
在 Windows 下:
c
unsigned long mode = 1; ioctlsocket(sockfd, FIONBIO, &mode); // 設(shè)置為非阻塞
常見(jiàn)非阻塞操作
recv():如果沒(méi)有數(shù)據(jù),立即返回-1,并設(shè)置errno = EWOULDBLOCK(Linux)或WSAEWOULDBLOCK(Windows)。send():如果發(fā)送緩沖區(qū)滿(mǎn),立即返回-1,表示無(wú)法立即發(fā)送。accept():如果沒(méi)有新連接,立即返回-1。connect():立即返回-1,并設(shè)置errno = EINPROGRESS(連接仍在進(jìn)行)。
示例(非阻塞 recv + 輪詢(xún))
c
char buffer[1024]; int bytes = recv(sockfd, buffer, sizeof(buffer), 0); if (bytes == -1) {
if (errno == EWOULDBLOCK) {
printf("No data available, try later.\n");
} else {
perror("recv error");
} } else {
printf("Received: %d bytes\n", bytes); }如果沒(méi)有數(shù)據(jù),
recv()不會(huì)阻塞,而是立即返回錯(cuò)誤,程序可以繼續(xù)執(zhí)行其他邏輯。
優(yōu)點(diǎn)
高并發(fā):?jiǎn)尉€程可以管理多個(gè) Socket(配合
select/epoll)。響應(yīng)性好:不會(huì)因?yàn)槟硞€(gè) Socket 卡住整個(gè)程序。
適合高性能服務(wù)器(如 Nginx、Redis)。
缺點(diǎn)
編程復(fù)雜:需要處理
EWOULDBLOCK和異步狀態(tài)。CPU 占用可能較高(如果使用忙輪詢(xún))。
3. 對(duì)比總結(jié)
| 特性 | 阻塞模式 | 非阻塞模式 |
|---|---|---|
| 調(diào)用行為 | 等待操作完成才返回 | 立即返回,成功/失敗需檢查 |
| 線程狀態(tài) | 掛起,不占用 CPU | 繼續(xù)執(zhí)行,可處理其他任務(wù) |
| 并發(fā)能力 | 低(需多線程) | 高(單線程 + I/O 多路復(fù)用) |
| 編程復(fù)雜度 | 簡(jiǎn)單 | 較復(fù)雜(需處理異步狀態(tài)) |
| 適用場(chǎng)景 | 簡(jiǎn)單客戶(hù)端、低并發(fā)服務(wù)器 | 高并發(fā)服務(wù)器(Web、游戲、實(shí)時(shí)系統(tǒng)) |
4. 如何選擇?
阻塞模式:適合簡(jiǎn)單應(yīng)用,如客戶(hù)端程序、低并發(fā)的服務(wù)端(如 FTP)。
非阻塞模式:適合高并發(fā)服務(wù)器(如 HTTP Server、WebSocket),通常結(jié)合
select/poll/epoll(Linux)或IOCP(Windows)使用。
5. 擴(kuò)展:I/O 多路復(fù)用(select/poll/epoll)
非阻塞 Socket 通常結(jié)合 I/O 多路復(fù)用 使用,避免忙輪詢(xún):
select()/poll():檢查多個(gè) Socket 是否可讀/可寫(xiě)(跨平臺(tái),但性能一般)。epoll()(Linux):高效事件通知機(jī)制,支持海量連接。kqueue()(FreeBSD/MacOS):類(lèi)似epoll。IOCP(Windows):異步 I/O 模型。
示例(epoll + 非阻塞 Socket)
c
int epfd = epoll_create1(0); struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET; // 邊緣觸發(fā)(Edge-Triggered)
ev.data.fd = sockfd; epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
while (1) {
int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
for (int i = 0; i < n; i++) {
if (events[i].data.fd == sockfd) {
// 有數(shù)據(jù)可讀,調(diào)用 recv(不會(huì)阻塞)
recv(sockfd, buf, sizeof(buf), 0);
}
} }總結(jié)
阻塞 Socket:簡(jiǎn)單但低效,適合低并發(fā)。
非阻塞 Socket:復(fù)雜但高效,適合高并發(fā),通常配合
epoll/select使用。
版權(quán)與免責(zé)聲明
凡本網(wǎng)注明“出處:維庫(kù)電子市場(chǎng)網(wǎng)”的所有作品,版權(quán)均屬于維庫(kù)電子市場(chǎng)網(wǎng),轉(zhuǎn)載請(qǐng)必須注明維庫(kù)電子市場(chǎng)網(wǎng),http://www.udpf.com.cn,違反者本網(wǎng)將追究相關(guān)法律責(zé)任。
本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點(diǎn)或證實(shí)其內(nèi)容的真實(shí)性,不承擔(dān)此類(lèi)作品侵權(quán)行為的直接責(zé)任及連帶責(zé)任。其他媒體、網(wǎng)站或個(gè)人從本網(wǎng)轉(zhuǎn)載時(shí),必須保留本網(wǎng)注明的作品出處,并自負(fù)版權(quán)等法律責(zé)任。
如涉及作品內(nèi)容、版權(quán)等問(wèn)題,請(qǐng)?jiān)谧髌钒l(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。
- 無(wú)線傳輸電路基礎(chǔ),射頻前端設(shè)計(jì)、天線匹配與鏈路預(yù)算計(jì)算2025/10/27 13:55:50
- ASK 解調(diào)的核心要點(diǎn)與實(shí)現(xiàn)方式2025/9/5 16:46:17
- 雙偶極子天線:結(jié)構(gòu)、特性與應(yīng)用全解析2025/9/3 10:29:21
- 幾種流行無(wú)線通信方式及其特點(diǎn)2025/9/2 17:14:12
- 解密射頻線纜彎曲衰減變化,掌握有效應(yīng)對(duì)策略2025/8/29 16:22:47
- 編碼器的工作原理及作用1
- 超強(qiáng)整理!PCB設(shè)計(jì)之電流與線寬的關(guān)系2
- 三星(SAMSUNG)貼片電容規(guī)格對(duì)照表3
- 電腦藍(lán)屏代碼大全4
- 國(guó)標(biāo)委發(fā)布《電動(dòng)汽車(chē)安全要求第3部分:人員觸電防護(hù)》第1號(hào)修改單5
- 通俗易懂談上拉電阻與下拉電阻6
- 繼電器的工作原理以及驅(qū)動(dòng)電路7
- 電容單位8
- 跟我學(xué)51單片機(jī)(三):?jiǎn)纹瑱C(jī)串口通信實(shí)例9
- 一種三極管開(kāi)關(guān)電路設(shè)計(jì)10









