首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Socket 通訊 Client 接收慢一拍?scanf 格式字串多吃換行符導致阻塞

     編輯:程式設計疑難解答

現象

Client 端 recv 一直收不到資料,或比預期延遲一輪。經排查發現發送端使用 scanf("%s\n", cmd) 讀取指令。

根本原因

scanf("%s\n", cmd) 中的 \n 會讓 scanf **持續讀取並丟棄空白字元(包含換行、空格、Tab)**,直到遇到非空白字元才返回。導致程式卡在等待「下一個非空白字元」,實際上資料已發送完畢,只是 scanf 沒有返回,後續發送邏輯無法執行。

修正方法

// 錯誤
scanf("%s\n", cmd);

// 正確:移除 \n,%s 已自動跳過前導空白並讀取到下一個空白
scanf("%s", cmd);

// 更安全:限制長度防止緩衝區溢位
scanf("%255s", cmd); // 假設 cmd[256]

延伸:網路程式輸入處理最佳實踐

  • 避免在生產代碼使用 scanf:無法處理含空格指令、緩衝區溢位風險、阻塞模式不利於事件迴圈。
  • 改用 fgets + 解析:
    char line[1024];
    while (fgets(line, sizeof(line), stdin)) {
        line[strcspn(line, "\r\n")] = 0; // 去除換行
        if (strlen(line) == 0) continue;
        // 解析 line,如 sscanf(line, "%s %d", cmd, &arg)
        send(sock, line, strlen(line), 0);
    }
    
  • 非阻塞 I/O + 多路複用:select/poll/epoll 同時監聽 stdin 與 socket,實現真正的並發互動。

總結

一個多餘的 \n 讓 scanf 吞噬了後續輸入機會,導致發送邏輯「慢一拍」甚至卡死。**網路程式輸入處理請拋棄 scanf,改用 fgets 或非阻塞事件模型**,才能構建健壯的通訊客戶端。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved