1. 程式人生 > >Linux下TCP迴圈接收資料的方式

Linux下TCP迴圈接收資料的方式

簡介

伺服器呼叫accept與客戶端建立連線,連線建立成功後,會返回一個fd,表示這條了連線的檔案描述符。之後呼叫recv函式接受連線的資訊。根據recv函式的原型,需要伺服器程式有一個接收緩衝區,實際情況可能緩衝區長度不夠,需要多次接收。這時候需要呼叫while迴圈接收。

如果連線建立成功,而且有資料發過來,但是此時的伺服器沒有及時處理,那麼訊息會放到緩衝區中,直到使用recv函式接收。也就是說,接收資料由核心完成並放到有關的緩衝區當中,recv的接收實際上是從核心中進行讀取。下面的20秒就是模擬這個過程。

程式碼例項

非阻塞方式,一次性接受完成後就退出

#include
<stdio.h>
#include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <thread> #include <chrono> #include <netinet/ip.h> #include <iostream> int main() { int ret, listenfd; struct sockaddr_in serv_addr; bzero
(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8001); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd < 0) { perror("socket() error\n"); return 0; } ret = bind(listenfd, (
struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (ret < 0) { perror("bind() error\n"); return 0; } ret = listen(listenfd, 1000); if (ret < 0) { perror("listen() error\n"); return 0; } int connfd = accept(listenfd, NULL, NULL); if (connfd < 0) { perror("accept() error\n"); return 0; } std::cout << "sleep for 20 seconds...\n"; std::this_thread::sleep_for(std::chrono::seconds(20)); std::cout << "weak up\n"; char buf[100]; memset(buf, 0, 100); // 這裡是非阻塞,如果是阻塞方式,把MAG_DONTWAIT改成0即可 while (recv(connfd, buf, sizeof(buf), MSG_DONTWAIT) > 0) { std::cout << "\nreceive message: " << buf; memset(buf, 0, sizeof(buf)); } return 0; }