基於TCP下MSG_PEEK的套接字接受緩衝區的排隊資料量分析
如何獲取已經排隊的資料量:
(1)、獲取套接字當中的資料量的目的是為了避免讀操作而堵塞在核心中(這樣會堵塞整個程式的進行), 為了解決這個問題, 我們可以使用非堵塞IO
(2)、在recv、recvfrom、recvnsg函式當中的flags引數標誌,我們可以使用MSG_PEEK標誌,僅僅讀取該套接字當中緩衝區當中的資料量,但是並不真真的讀取該資料,也可以使用MSG_DONTWAIT | MSG_PEEK相結合。但是我們需要注意的是,(針對tcp)可能兩次呼叫recv函式返回的值不同,因為兩次呼叫函式之間可能會資料到來。就針對UDP套接字而言,前一次呼叫recvfrom函式加上MSG_PEEK標誌檢視接收對列的資料量,後一次不加該標誌呼叫recvfrom函式讀取資料,那麼兩次的返回值(資料報大小、內容、發報者地址)將會是完全相同。
(3)、一些支援ioctl的FIONREAD命令。改命令第三個值-結果引數也會指向某個整數的一個指標,核心通過該整數返回的值就是套接字接收對列裡面當前所有資料的位元組數;而對於UDP而言,就是所有的已排隊資料報的總和的位元組數大小。因為針對UDP中返回值包括Ip地址和埠號(IPv4是16位元組,IPv6是24位元組)。
TCP連線的條件下 程式碼如下
客戶端核心程式碼片段如下:
程式碼分析:我相信自己看得懂#include "unp.h" void str_cli(FILE *fp, int sockfd) { int maxfdp, stdineof = 0; char sendbuf[MAXLINE], recvbuf[MAXLINE]; fd_set rset; FD_ZERO(&rset); int num; for(;;){ if(stdineof == 0) FD_SET(fileno(fp), &rset); FD_SET(sockfd, &rset); maxfdp = fileno(fp); if((num = Select(maxfdp + 1, &rset, NULL, NULL, NULL)) < 0){ if(errno == EINTR) { fprintf(stdout, "semaphore lead to system call\n"); continue; }else{ fprintf(stdout, "select error\n"); } } if(FD_ISSET(sockfd, &rset)){ if(Readline(sockfd, recvbuf, MAXLINE) <= 0){ if(stdineof == 1){ return; } if(errno == EINTR){ fprintf(stdout, "system call interrupted\n"); continue; }else{ fprintf(stdout, "read error\n"); } } fprintf(stdout, "read error\n"); Fputs(recvbuf, stdout); } if(FD_ISSET(fileno(fp), &rset)){ if(Fgets(sendbuf, MAXLINE, fp) == NULL){ FD_CLR(fileno(fp), &rset); Shutdown(sockfd, SHUT_WR); stdineof = 1; continue; } Writen(sockfd, sendbuf, strlen(sendbuf)); } } }
tcp伺服器端核心程式碼如下
程式碼分析:#include "unp.h" void _str_echo(int sockfd) { char recvbuf[MAXLINE]; int n; for(;;){ n = Recv(sockfd, recvbuf, MAXLINE, MSG_PEEK); if(0 == n) break; //server close connect else{ int npend; sleep(1); Ioctl(sockfd, FIONREAD, &npend); fprintf(stdout, "%d bytes from PEEK, %d bytes pending\n", n,npend); n = Read(sockfd, recvbuf, MAXLINE); recvbuf[n] = 0; Fputs(recvbuf, stdout); } } }
1、MSG_PEEK會把資料讀到緩衝區,但是並不會清理套接字中的資料,還可以供其他程序讀取。
2、ioctl的FIONREAD也可以讀取套接字中緩衝區的資料。
執行結果如下:
相關推薦
基於TCP下MSG_PEEK的套接字接受緩衝區的排隊資料量分析
如何獲取已經排隊的資料量: (1)、獲取套接字當中的資料量的目的是為了避免讀操作而堵塞在核心中(這樣會堵塞整個程式的進行), 為了解決這個問題, 我們可以使用非堵塞IO (2)、在recv、recvfrom、recvnsg函式當中的flags引數標誌,我們可以使用MSG_P
基於TCP的socket套接字的網路程式設計(客戶端/服務端模式)
於資料完整性要求較高的場合,就應採用TCP協議。 IP網路層提供IP定址和路由。因為在網路上資料可以經由多條線路到達目的地,網路層負責找出最佳的傳輸線路。 IP地址與資料包: IP層就是把資料分組從一個主機跨越千山萬水搬運到另外一主機, 並且這搬運服務一點都不可靠, 丟包、
一、基於linux下TCP\IP協議套接字(socket)初識
在網際網路的世界中,不同的電腦之間需要進行資料交流,那麼他們就需要一個統一的規範,來確定怎麼樣進行交流。根據國際標準化組織ISO定義的標準,網路結構按照不同的功能分為7層,分別是物理層、資料鏈路層、網路層、傳輸層、會話層、表示層和應用層。在TCP/IP協體系中,
Python--網絡編程-----基於UDP協議的套接字
data soc nbsp net 服務 int ddr bind 客戶 服務端: 1 from socket import * 2 3 server = socket(AF_INET, SOCK_DGRAM) 4 server.bind((‘127.0.0.1
建立一個TCP流式套接字
#python網路套接字模組 from socket import * HOST = '172.60.50.218' PORT = 8888 ADDR = (HOST,PORT) BUFFERSIZE = 1024 #建立一個tcp流式套接字 sockfd = socket(AF_INET,SOCK_
基於udp協議的套接字
sendto 遠程 如果 class col win 文件 時間服務器 發送 tcp:發送數據可靠,需要建立連接,存在粘包現象udp:傳送數據不可靠,不用建立連接,發數據效率高,不存在粘包現象 服務端 from socket import * server = sock
計算機網路自頂向下方法套接字程式設計作業
本部落格是針對,《計算機網路自頂向下方法》一書第二章後面套接字程式設計作業, 所有程式碼均已上傳至我的github:https://github.com/inspurer/ComputerNetwork 所有程式碼均本人親自編寫,有問題歡迎評論交流; 如需轉載請聯絡:[email
TCP協議和套接字、IP層之間的介面
1、TCP和套接字層之間的介面 TCP和套接字之間的介面資料結構是struct proto,這個結構體的元素是一系列的函式指標,從tcp_close到tcp_shutdown函式是tcp連線管理處理函式。TCP資料接受函式是tcp_recvmsg和tcp_v4_do_rcv函式實現。struct
[實驗]關閉TCP監聽套接字對已建立連線的影響
先說結果吧,結果是無影響,已建立的連線依然可以正常使用。 實驗環境 windows10,vs2010 實驗過程 伺服器採用VC程式設計,客戶端使用TCP除錯軟體。 伺服器工作流程 1、建立監聽套接字socket1,繫結埠17000。 2、使用listen函式監聽
TCP和UDP套接字程式設計 (java實現)
在瞭解網路程式設計之前,我們先了解一下什麼叫套接字 套接字即指同一臺主機內應用層和運輸層之間的介面 由於這個套接字是建立在網路上建立網路應用的可程式設計介面 因此也將套接字稱為應用程式和網路之間的應用程式程式設計介面! 關於TCP和UDP這裡就不作太多介紹了,我們知道TCP是面向連
TCP和UDP套接字編程 (java實現)
dpa byte 傳輸 不可 字節數 readline exception 設計 鍵盤輸入 在了解網絡編程之前,我們先了解一下什麽叫套接字 套接字即指同一臺主機內應用層和運輸層之間的接口 由於這個套接字是建立在網絡上建立網絡應用的可編程接口 因此也將套接字稱為應用程序
Java 網路程式設計(五) 使用TCP/IP的套接字(Socket)進行通訊
使用TCP/IP的套接字(Socket)進行通訊 套接字Socket的引入 為了能夠方便地開發網路應用軟體,由美國伯克利大學在Unix上推出了一種應用程式訪問通訊協議的作業系統用呼叫socket(套接字)。 socket的出現,使程式設計師可以很方便地訪問TCP/
TCP流式套接字的事件物件I/O管理WSAEventSelect程式設計
/************************************************************************/ /* 事件物件I/O管理程式例項 */ /**************
MFC基於select模型的套接字類之伺服器(8)
4 停止伺服器 為CTCPSocket_Server類新增訪問許可權為public的成員函式StopServer()。在該函式中主要完成的工作是關閉“2.3 StartServer()函式”中提到了用於接受客戶端連線的執行緒和用於接收客戶端資料的執行緒。 4.1 結束接受
VC中TCP實現 非同步套接字程式設計的原理+程式碼
所謂的非同步套接字程式設計就是 呼叫了 如下函式 WSAAsyncSelect 設定了 套接字的狀態為非同步,有關函式我會在下面詳細介紹。。。 非同步套接字解決了 套接字程式設計過程中的堵塞問題 ...... 什麼是堵塞?請看下面 你可能有過這樣的體會 在
TCP流式套接字的非同步事件WSAAsyncSelect程式設計
#define WM_SOCKET WM_USER+101 #include <WINSOCK2.H> /*#include <windows.h>*/ #pragma comment(lib,"WS2_32") //----------------視窗過程函式的宣告---------
TCP/IP(7)-TCP Server與TCP Client(linux套接字)
前面幾篇文章談到的關於TCP/IP應用層以下的協議,這些協議最終是在作業系統核心中實現的,套接字API是unix系統用於網路連線的介面,後來被移植到windows系統中,就有了winsock。 TCP的Client/Server模式 在TCP/IP協議中
Linux網路程式設計——原始套接字例項:MAC 頭部報文分析
通過《Linux網路程式設計——原始套接字程式設計》得知,我們可以通過原始套接字以及 recvfrom( ) 可以獲取鏈路層的資料包,那我們接收的鏈路層資料包到底長什麼樣的呢? MAC 頭部(有線區域網) 注意:CRC、PAD 在組包時可以忽略 鏈路層資料包的其中一
基於threading模組下Thread,實現多執行緒TCP套接字通訊
伺服器 import socket from threading import Thread import struct, json IP = '127.0.0.1' PORT = 8080 ADD = (IP, PORT) server = socket.socket
python基礎之socket編程-------基於tcp的套接字實現遠程執行命令的操作
logs lose stream res std 遠程控制 python log out 遠程實現cmd功能: import socket import subprocess phone=socket.socket(socket.AF_INET,socket.SOC