<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      posix API的一些理解

      TCP Posix API的理解

      我們主要從TCP連接講解整個的流程。

      • 連接的建立
      • 消息的收發
      • 連接的斷開

      連接的建立

      先看一下一個TCP server的創建過程。

      #include<stdio.h>
      #include<sys/socket.h>
      #include<netinet/in.h>
      #include<errno.h>
      #include<unistd.h>
      #include<string.h>
      #include<sys/types.h>
      #include<arpa/inet.h>
      #include<netinet/in.h>
      using namespace std;
      
      int main(int argc, char *argv[])
      {
      	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
      	if (sockfd<0)
      	{
      		printf("Create Socket failed!code:%d\n", errno);
      		return -1;
      	}
      	struct sockaddr_in ServerAddr;
      	
      
      	memset(&ServerAddr, 0, sizeof(ServerAddr));
      	
      	ServerAddr.sin_family = AF_INET;
      	ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
      	ServerAddr.sin_port = htons(9999);
      	if (bind(sockfd, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr))<0)
      	{
      		printf("bind function is failed!error code:%d\n", errno);
      		return -1;
      	}
      	if (listen(sockfd,10)<0)
      	{
      		printf("listen function is failed!error code:%d\n", errno);
      		return -1;
      	}
      	
      	//開始接受TCP連接
      	while (true)
      	{
      		socklen_t len = 0;
      		int client_sock = accept(sockfd, (struct sockaddr*)&socket, &len);
      		if (client_sock<0)
      		{
      			printf("accept() error ! error code:%d\n", errno);
      			return -1;
      		}
      		
      		char buf[2048];
      		while(1)
              {
                  memset(buf,'\0',sizeof(buf));
                  read(client_sock,buf,sizeof(buf));  
      
      
      			printf("client:# %s\n",buf);
      
                  printf("server:$ ");
      
                  memset(buf,'\0',sizeof(buf));
      
                  fgets(buf,sizeof(buf),stdin);
                  buf[strlen(buf)-1]='\0';
                  if(strncasecmp(buf,"quit",4)==0)
                  {
                      printf("quit\n");
                      break;
                  }
                  write(client_sock,buf,strlen(buf)+1);
                  printf("wait...\n");
              }
              close(client_sock);
          }
      	
      	close(sockfd);	
      	
      	return 0;
      }
      

      準備一張TCP狀態轉換圖

      三次握手的過程。

      比較常會被問到的為什么3次握手?
      其實就是需要3次確定連接。

      其次就是對應的API的階段是什么。
      在服務器端調用listen以后,客戶端開始進行連接的時候,
      一般都會在第一次握手的時候,維護一個鏈表,表明已經進行過第一次握手的半連接。
      其次就是在第三次握手以后,就會將這個連接,保存到另外一個全連接的隊列,表示這個連接已經三次握手完畢,可以進行連接。

      然后我們在服務端的時候,就可以調用accept進行連接的接受。
      從我們的已經準備的好的全連接的隊列中,取出一個連接,在進行消息的收發。

      我們再討論一下 listen中的backlog這個參數的作用。

      這個參數根據文檔來說是這樣的

      The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.
      If  a connection request arrives when the queue is full, the client may receive an error with an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may  be  ignored  so  that  a later reattempt at connection succeeds.
      

      而我們可以從文檔中看出來,這個隊列主要指的是全連接隊列的長度,指定我們全連接隊列的長度的大小。

      順便說一下ddos的攻擊問題,我的連接就是有大量的經過第一次握手的連接的客戶端和目標服務器進行連接,導致新的連接。

      數據發送階段

      這里我們只考慮我們可以控制的階段,比如消息的收發,對于消息在公網區域是如何傳輸的,我們是無法進行控制以及追蹤的,因此我們就考慮消息的收發。
      普遍存在三種情況,

      • 單條send
      • 循環send
      • 發送很多的數據的send
        首先,有一點,在我們創建完一個TCP連接的時候,就會知道源IP,目的IP,源端口,目的端口,以及對應的協議類型,也就存在一個TCB的概念。

      由于第一種的send的情況比較普遍,就是直接的收發就可以了,我們在實際調用send的時候,并不是返回是整數,就代表著我們的信息已經發送成功了,其實只是將我們想要發送的信息黏貼在內核的發送緩沖區中,TCP只是能保證我們的消息順序是順序的。這樣就在我們循環發送的消息的時候,可能就會出現一個問題,就是TCP粘包的問題。

      怎么解決粘包的問題?

      • 增加包長度的信息
      • 增加分隔符
        通過這兩種方法就能解決TCP粘包的問題了。

      最后一種就是發送一個文件之類的,規定一個消息的結構,并發送完畢就可以了。

      連接斷開

      網線斷了(網線剪短),網卡停止供電,網卡設備會重啟,你所有的連接都會重啟。
      再次供電的時候,就會有變化。應用程序就通過心跳包,來判斷連接是否已經斷開。客戶端直接宕機,也是通過心跳包來進行判斷。

      這里主要就是討論就是如何解決close_wait的情況。
      主要是由于recv返回0,沒有調用close。
      業務數據和網絡接口,可以做成異步的。

      推薦一個零聲學院免費教程,個人覺得老師講得不錯,
      分享給大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
      fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,
      TCP/IP,協程,DPDK等技術內容,點擊立即學習:
      服務器
      音視頻
      dpdk
      Linux內核

      posted @ 2022-11-20 03:59  飄雨的河  閱讀(157)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 黑人欧美一级在线视频| 97免费人妻在线视频 | 999精品全免费观看视频| 四虎影视www在线播放| 国产69精品久久久久人妻刘玥| 91色老久久精品偷偷性色| 日韩激情一区二区三区| 久久亚洲精精品中文字幕| 在线中文字幕国产精品| 人妻少妇偷人无码视频| 国产亚洲精品久久久久婷婷图片| 日本中文一二区有码在线| 国产精品制服丝袜白丝| 亚洲色精品vr一区区三区| 国产精品福利一区二区三区| 日韩乱码人妻无码中文字幕视频 | 天天影视色香欲综合久久| 午夜A理论片在线播放| 成人久久精品国产亚洲av| 亚洲少妇人妻无码视频| av偷拍亚洲一区二区三区| 江川县| gogogo高清在线观看视频中文| 亚洲一区二区三区在线播放无码| 成 人免费va视频| 视频一区二区三区四区五区| 精品人妻人人做人人爽夜夜爽| 一级片黄色一区二区三区| 中国老太婆video| 国产精品中文字幕日韩| 国产视频 视频一区二区| 麻豆a级片| 婷婷丁香五月亚洲中文字幕| 亚洲人ⅴsaⅴ国产精品| 激情亚洲内射一区二区三区| 午夜av高清在线观看| 国产迷姦播放在线观看| 国偷自产一区二区三区在线视频| 亚洲三级香港三级久久| 精品少妇人妻av无码专区| 成武县|