国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(5)

這篇具有很好參考價值的文章主要介紹了【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(5)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

?????????Socket 是網(wǎng)絡協(xié)議棧暴露給編程人員的 API,相比復雜的計算機網(wǎng)絡協(xié)議,API 對關鍵操作和配置數(shù)據(jù)進行了抽象,簡化了程序編程。

? ? ? ? 本文講述的 socket 內(nèi)容源自 Linux man。本文主要對各 API 進行詳細介紹,從而更好的理解 socket 編程。


connect

connect()????????? ?遵循 POSIX.1 - 2008

1.庫

標準 c 庫,libc, -lc

2.頭文件

<sys/socket.h>

3.接口定義

        int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen);

4.接口描述

? ? ? ? connect() 系統(tǒng)調(diào)用在 sockfd 指定的 socket 上連接 addr 指定的地址,addrlen 參數(shù)指定了 addr 的大小,addr 地址格式取決于 socket 的地址空間,可以參考 socket(2)。

? ? ? ? 如果 socket 是 SOCK_DGRAM?類型,那么 addr 是發(fā)送報文的默認地址,也是唯一接收報文的地址。如果 socket 類型是 SOCK_STREAM 或者 SOCK_SEQPACKET,那么這個調(diào)用就是嘗試和綁定了 addr 地址的 socket 建立連接。

? ? ? ? 一些協(xié)議套接字(比如 UNIX 流套接字)只能成功連接一次。

? ? ? ? 一些協(xié)議套接字(比如 UNIX TCP 套接字和網(wǎng)絡數(shù)據(jù)報套接字)可以多次 connect() 來修改連接。

? ? ? ? 一些協(xié)議套接字(比如 UNIX TCP 套接字和網(wǎng)絡數(shù)據(jù)報套接字)可以通過將 sockaddr 的 sa_family 設置為 AF_UNSPEC 來消除連接,之后 socket 就可以連接到其他地址了。(AF_UNSPEC 在 Linux 2.2 之后支持)。

5.返回值

? ? ? ? 如果連接或者綁定成功,那么返回 0。

? ? ? ? 發(fā)生錯誤時,返回 -1,并設置errno 來指示錯誤類型。

? ? ? ? 錯誤值定義如下(這里指示普通 socket 的錯誤,還可能存在 domain-specific 錯誤碼):

EACCES UNIX 域套接字通過路徑名唯一標識,并且是套接字文件是沒有寫權限的,路徑中任何一級的搜索權限也是沒有的,可以參考 path_resolution(7)
EACCES/EPERM 用戶嘗試連接到一個廣播地址,卻沒有設置套接字的廣播標記,或者請求被防火墻規(guī)則攔截了
EACCES 如果開啟了 SELinux 策略,也可能會導致連接被拒絕(比如策略規(guī)定 HTTP 代理只能連接到 HTTP 服務器關聯(lián)的端口,而 HTTP 代理卻連接了其他端口)
EADDRINUSE 本地地址已經(jīng)在用了
EADDRNOTAVAIL (網(wǎng)絡域套接字)sockfd 指定的套接字沒有綁定到地址,并且在嘗試將其綁定到臨時端口時,臨時端口用盡了
EAFNOSUPPORT 地址家族不正確
EAGAIN 對于非阻塞的 UNIX 域套接字,套接字是非阻塞的,連接無法立即完成。對于其他套接字家族,這個錯誤標識路由緩存沒有足夠的條目了
EALREADY 套接字是非阻塞的,并且之前的連接嘗試還沒有完成
EBADF sockfd 不是一個打開的文件描述符
ECONNREFUSED connect() 操作的流套接字發(fā)現(xiàn)沒有人在監(jiān)聽對應的遠程地址
EFAULT 套接字結構地址超出用戶地址空間
EINPROGRESS 套接字是非阻塞的,連接不能立即完成。(UNIX 域套接字會返回 EAGAIN)??梢酝ㄟ^ select(2) 或者 poll(2) 查看套接字的可寫事件,來確定連接完成。select(2) 指示可寫后,使用 getsockopt(2) 來讀取 SOL_SOCKET 級的 SO_ERROR 選項,來確定連接完全成功(SO_ERROR 為 0)或者未成功(SO_ERROR 為這里列出來的普通錯誤)。
EINTR 系統(tǒng)調(diào)用被信號打斷
EISCONN 套接字已經(jīng)連接
ENETUNREACH 網(wǎng)絡不可達
ENOTSOCK 文件描述符并沒有指向一個套接字
EPROTOTYPE 該套接字不支持指定的通信協(xié)議。這個錯誤可能在出現(xiàn)在連接一個 UNIX 域報文套接字到一個流套接字
ETIMEDOUT 連接超時??赡苁欠掌魈α艘灾劣跓o法接收新的連接。注意:當服務器開啟 syncookies 時,IP 套接字的超時可能會非常長。

6.注意

? ? ? ?如果 connect() 失敗,那么套接字的狀態(tài)是未知的。一個易于移植的程序應該關閉該套接字應該再創(chuàng)建一個新套接字,重新連接。

7.代碼

? ? ? ? 這里我們展示下 select() 的用法示例,來將最近幾篇內(nèi)容串起來:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>

#define SERVER_PORT  12345

#define TRUE             1
#define FALSE            0

main (int argc, char *argv[])
{
   int    i, len, rc, on = 1;
   int    listen_sd, max_sd, new_sd;
   int    desc_ready, end_server = FALSE;
   int    close_conn;
   char   buffer[80];
   struct sockaddr_in6   addr;
   struct timeval       timeout;
   struct fd_set        master_set, working_set;

   /*************************************************************/
   /* Create an AF_INET6 stream socket to receive incoming      */
   /* connections on                                            */
   /*************************************************************/
   listen_sd = socket(AF_INET6, SOCK_STREAM, 0);
   if (listen_sd < 0)
   {
      perror("socket() failed");
      exit(-1);
   }

   /*************************************************************/
   /* Allow socket descriptor to be reuseable                   */
   /*************************************************************/
   rc = setsockopt(listen_sd, SOL_SOCKET,  SO_REUSEADDR,
                   (char *)&on, sizeof(on));
   if (rc < 0)
   {
      perror("setsockopt() failed");
      close(listen_sd);
      exit(-1);
   }

   /*************************************************************/
   /* Set socket to be nonblocking. All of the sockets for      */
   /* the incoming connections will also be nonblocking since   */
   /* they will inherit that state from the listening socket.   */
   /*************************************************************/
   rc = ioctl(listen_sd, FIONBIO, (char *)&on);
   if (rc < 0)
   {
      perror("ioctl() failed");
      close(listen_sd);
      exit(-1);
   }

   /*************************************************************/
   /* Bind the socket                                           */
   /*************************************************************/
   memset(&addr, 0, sizeof(addr));
   addr.sin6_family      = AF_INET6;
   memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
   addr.sin6_port        = htons(SERVER_PORT);
   rc = bind(listen_sd,
             (struct sockaddr *)&addr, sizeof(addr));
   if (rc < 0)
   {
      perror("bind() failed");
      close(listen_sd);
      exit(-1);
   }

   /*************************************************************/
   /* Set the listen back log                                   */
   /*************************************************************/
   rc = listen(listen_sd, 32);
   if (rc < 0)
   {
      perror("listen() failed");
      close(listen_sd);
      exit(-1);
   }

   /*************************************************************/
   /* Initialize the master fd_set                              */
   /*************************************************************/
   FD_ZERO(&master_set);
   max_sd = listen_sd;
   FD_SET(listen_sd, &master_set);

   /*************************************************************/
   /* Initialize the timeval struct to 3 minutes.  If no        */
   /* activity after 3 minutes this program will end.           */
   /*************************************************************/
   timeout.tv_sec  = 3 * 60;
   timeout.tv_usec = 0;

   /*************************************************************/
   /* Loop waiting for incoming connects or for incoming data   */
   /* on any of the connected sockets.                          */
   /*************************************************************/
   do
   {
      /**********************************************************/
      /* Copy the master fd_set over to the working fd_set.     */
      /**********************************************************/
      memcpy(&working_set, &master_set, sizeof(master_set));

      /**********************************************************/
      /* Call select() and wait 3 minutes for it to complete.   */
      /**********************************************************/
      printf("Waiting on select()...\n");
      rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);

      /**********************************************************/
      /* Check to see if the select call failed.                */
      /**********************************************************/
      if (rc < 0)
      {
         perror("  select() failed");
         break;
      }

      /**********************************************************/
      /* Check to see if the 3 minute time out expired.         */
      /**********************************************************/
      if (rc == 0)
      {
         printf("  select() timed out.  End program.\n");
         break;
      }

      /**********************************************************/
      /* One or more descriptors are readable.  Need to         */
      /* determine which ones they are.                         */
      /**********************************************************/
      desc_ready = rc;
      for (i=0; i <= max_sd  &&  desc_ready > 0; ++i)
      {
         /*******************************************************/
         /* Check to see if this descriptor is ready            */
         /*******************************************************/
         if (FD_ISSET(i, &working_set))
         {
            /****************************************************/
            /* A descriptor was found that was readable - one   */
            /* less has to be looked for.  This is being done   */
            /* so that we can stop looking at the working set   */
            /* once we have found all of the descriptors that   */
            /* were ready.                                      */
            /****************************************************/
            desc_ready -= 1;

            /****************************************************/
            /* Check to see if this is the listening socket     */
            /****************************************************/
            if (i == listen_sd)
            {
               printf("  Listening socket is readable\n");
               /*************************************************/
               /* Accept all incoming connections that are      */
               /* queued up on the listening socket before we   */
               /* loop back and call select again.              */
               /*************************************************/
               do
               {
                  /**********************************************/
                  /* Accept each incoming connection.  If       */
                  /* accept fails with EWOULDBLOCK, then we     */
                  /* have accepted all of them.  Any other      */
                  /* failure on accept will cause us to end the */
                  /* server.                                    */
                  /**********************************************/
                  new_sd = accept(listen_sd, NULL, NULL);
                  if (new_sd < 0)
                  {
                     if (errno != EWOULDBLOCK)
                     {
                        perror("  accept() failed");
                        end_server = TRUE;
                     }
                     break;
                  }

                  /**********************************************/
                  /* Add the new incoming connection to the     */
                  /* master read set                            */
                  /**********************************************/
                  printf("  New incoming connection - %d\n", new_sd);
                  FD_SET(new_sd, &master_set);
                  if (new_sd > max_sd)
                     max_sd = new_sd;

                  /**********************************************/
                  /* Loop back up and accept another incoming   */
                  /* connection                                 */
                  /**********************************************/
               } while (new_sd != -1);
            }

            /****************************************************/
            /* This is not the listening socket, therefore an   */
            /* existing connection must be readable             */
            /****************************************************/
            else
            {
               printf("  Descriptor %d is readable\n", i);
               close_conn = FALSE;
               /*************************************************/
               /* Receive all incoming data on this socket      */
               /* before we loop back and call select again.    */
               /*************************************************/
               do
               {
                  /**********************************************/
                  /* Receive data on this connection until the  */
                  /* recv fails with EWOULDBLOCK.  If any other */
                  /* failure occurs, we will close the          */
                  /* connection.                                */
                  /**********************************************/
                  rc = recv(i, buffer, sizeof(buffer), 0);
                  if (rc < 0)
                  {
                     if (errno != EWOULDBLOCK)
                     {
                        perror("  recv() failed");
                        close_conn = TRUE;
                     }
                     break;
                  }

                  /**********************************************/
                  /* Check to see if the connection has been    */
                  /* closed by the client                       */
                  /**********************************************/
                  if (rc == 0)
                  {
                     printf("  Connection closed\n");
                     close_conn = TRUE;
                     break;
                  }

                  /**********************************************/
                  /* Data was received                          */
                  /**********************************************/
                  len = rc;
                  printf("  %d bytes received\n", len);

                  /**********************************************/
                  /* Echo the data back to the client           */
                  /**********************************************/
                  rc = send(i, buffer, len, 0);
                  if (rc < 0)
                  {
                     perror("  send() failed");
                     close_conn = TRUE;
                     break;
                  }

               } while (TRUE);

               /*************************************************/
               /* If the close_conn flag was turned on, we need */
               /* to clean up this active connection.  This     */
               /* clean up process includes removing the        */
               /* descriptor from the master set and            */
               /* determining the new maximum descriptor value  */
               /* based on the bits that are still turned on in */
               /* the master set.                               */
               /*************************************************/
               if (close_conn)
               {
                  close(i);
                  FD_CLR(i, &master_set);
                  if (i == max_sd)
                  {
                     while (FD_ISSET(max_sd, &master_set) == FALSE)
                        max_sd -= 1;
                  }
               }
            } /* End of existing connection is readable */
         } /* End of if (FD_ISSET(i, &working_set)) */
      } /* End of loop through selectable descriptors */

   } while (end_server == FALSE);

   /*************************************************************/
   /* Clean up all of the sockets that are open                 */
   /*************************************************************/
   for (i=0; i <= max_sd; ++i)
   {
      if (FD_ISSET(i, &master_set))
         close(i);
   }
}

下一篇 【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(6)???????文章來源地址http://www.zghlxwxcb.cn/news/detail-716033.html

到了這里,關于【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(5)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(8)

    ?????????Socket 是網(wǎng)絡協(xié)議棧暴露給編程人員的 API,相比復雜的計算機網(wǎng)絡協(xié)議,API 對關鍵操作和配置數(shù)據(jù)進行了抽象,簡化了程序編程。 ? ? ? ? 本文講述的 socket 內(nèi)容源自 Linux man。本文主要對各 API 進行詳細介紹,從而更好的理解 socket 編程。 ? ? ? ?本文主要描述

    2024年02月08日
    瀏覽(28)
  • 【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(11)

    ?????????Socket 是網(wǎng)絡協(xié)議棧暴露給編程人員的 API,相比復雜的計算機網(wǎng)絡協(xié)議,API 對關鍵操作和配置數(shù)據(jù)進行了抽象,簡化了程序編程。 ? ? ? ? 本文講述的 socket 內(nèi)容源自 Linux man。本文主要對各 API 進行詳細介紹,從而更好的理解 socket 編程。 遵循 POSIX.1-2008 ? ? ?

    2024年02月08日
    瀏覽(26)
  • 【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(2)

    ?????????Socket 是網(wǎng)絡協(xié)議棧暴露給編程人員的 API,相比復雜的計算機網(wǎng)絡協(xié)議,API 對關鍵操作和配置數(shù)據(jù)進行了抽象,簡化了程序編程。 ? ? ? ? 本文講述的 socket 內(nèi)容源自 Linux man。本文主要對各 API 進行詳細介紹,從而更好的理解 socket 編程。 遵循 POSIX.1 - 2008 ? ?

    2024年02月09日
    瀏覽(25)
  • 【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(4)

    ?????????Socket 是網(wǎng)絡協(xié)議棧暴露給編程人員的 API,相比復雜的計算機網(wǎng)絡協(xié)議,API 對關鍵操作和配置數(shù)據(jù)進行了抽象,簡化了程序編程。 ? ? ? ? 本文講述的 socket 內(nèi)容源自 Linux man。本文主要對各 API 進行詳細介紹,從而更好的理解 socket 編程。 poll()????????? ?遵

    2024年02月09日
    瀏覽(36)
  • 【計算機網(wǎng)絡】網(wǎng)絡編程接口 Socket API 解讀(1)

    ?????????Socket 是網(wǎng)絡協(xié)議棧暴露給編程人員的 API,相比復雜的計算機網(wǎng)絡協(xié)議,API 對關鍵操作和配置數(shù)據(jù)進行了抽象,簡化了程序編程。 ? ? ? ? 本文講述的 socket 內(nèi)容源自 Linux man。本文主要對各 API 進行詳細介紹,從而更好的理解 socket 編程。 遵循 POSIX.1 - 2001、POS

    2024年02月09日
    瀏覽(35)
  • 計算機網(wǎng)絡--網(wǎng)絡編程(1)

    計算機網(wǎng)絡--網(wǎng)絡編程(1)

    簡單認識一下傳輸層中的UDP和TCP: TCP:有鏈接,可靠傳輸,面向字節(jié)流,全雙工 UDP:無連接,不可靠傳輸,面向數(shù)據(jù)報,全雙工 有鏈接類似于打電話,通了就是有鏈接。沒通就一直在等待。 無連接類似于發(fā)短信,只管發(fā),不管到。 可靠傳輸就是保證信息傳輸?shù)目煽啃?。?/p>

    2024年02月11日
    瀏覽(34)
  • 【計算機網(wǎng)絡】4 Socket網(wǎng)絡編程

    【計算機網(wǎng)絡】4 Socket網(wǎng)絡編程

    目錄 寫在前面的話 概覽 環(huán)境 URL請求程序: 2. 系統(tǒng)時間查詢 服務端 T_TCPServer.py代碼 客戶端 T_TCPClient.py代碼 運行效果 3. 網(wǎng)絡文件傳輸 服務端 TF_TCPServer.py代碼 運行效果(后面加了遠程功能,效果圖暫時還在本地) 4. 網(wǎng)絡聊天室 服務端 UDPServer.py代碼 客戶端 UDPClient.py代碼 運

    2024年02月01日
    瀏覽(33)
  • 【計算機網(wǎng)絡】網(wǎng)絡編程套接字(一)

    【計算機網(wǎng)絡】網(wǎng)絡編程套接字(一)

    目錄 1.預備知識 1.1.理解源IP地址和目的IP地址 1.2.認識端口號 1.2.1.理解\\\"端口號\\\"和\\\"進程ID\\\" 1.2.2.理解源端口號和目的端口號 1.3.認識TCP/UDP協(xié)議 1.3.1.TCP協(xié)議 1.3.2.UDP協(xié)議 1.4.網(wǎng)絡字節(jié)序 網(wǎng)絡字節(jié)序和主機字節(jié)序的轉(zhuǎn)換 2.socket編程接口 2.1.sockaddr結構 struct sockaddr_in 的具體結構: 2.

    2024年02月08日
    瀏覽(34)
  • 【計算機網(wǎng)絡】網(wǎng)絡編程套接字(二)

    【計算機網(wǎng)絡】網(wǎng)絡編程套接字(二)

    簡單TCP服務器實現(xiàn) 我們將會使用到的頭文件放在 comm.h 文件中 創(chuàng)建套接字 創(chuàng)建過程和UDP服務器幾乎完全一樣,除了使用的是TCP服務器使用的是流式服務(SOCK_STREAM),UDP使用的是數(shù)據(jù)包服務(SOCK_DGRAM) 服務器綁定 綁定的過程和UDP服務器也是相同的,可以看著復習一下 定義好 st

    2024年02月13日
    瀏覽(34)
  • 計算機網(wǎng)絡---網(wǎng)絡編程套接字(一)

    計算機網(wǎng)絡---網(wǎng)絡編程套接字(一)

    ? 計算機網(wǎng)絡—網(wǎng)絡編程套接字之UDP數(shù)據(jù)報套接字編程 作者介紹: ??作者:偷偷敲代碼的青花瓷????? ??作者的Gitee:代碼倉庫 ??系列文章推薦:計算機網(wǎng)絡 ——網(wǎng)絡原理之初識 ??我和大家一樣都是熱愛編程?,很高興能在此和大家分享知識,希望在分享知識的同時,能和大

    2023年04月09日
    瀏覽(78)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包