網路IPC, socket(4): 資料轉送函數

來源:互聯網
上載者:User

    前面已經說過, 對檔案的操作函數read/write也同樣可以操作socket描述符, 就把socket描述符當作一個檔案來處理. 所以在socket上使用read/write是有意義的, 可以傳遞socket描述符到那些本來設計為處理本地檔案的函數, 還可以安排socket描述符到執行進程的子進程, 該子進程也不需要瞭解socket.

    雖然read/write可以執行socket上的資料轉送, 但它不能指定選項, 不能從多個用戶端接收資料, 也不能向多個用戶端發送資料. 如果需要實現這些, 就需要使用socket提供的函數了.

 

1. 發送資料:

  • ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);
    • 使用時必須已經串連.
    • 參數buf, nbytes和write中的含義一致.
    • flags是socket的調用標誌, 可以是:
      • MSG_DONTROUTE: 不走路由, 也就是說資料不可越出本網.
      • MSG_DONTWAIT: 非阻塞操作, 等價於write使用O_NONBLOCK.
      • MSG_EOR: 如果協議支援, 此為記錄結束.
      • MSG_OOB: 如果協議支援, 發送帶外資料.
    • send成功返回時, 僅僅表示資料已經準確無誤地發送到了網路上, 而不關心接收端.

 

  • ssize_t sendto(int sockfd, const void *buf, size_t nbytes, int flags,

 const struct sockaddr *destaddr, socklen_t destlen);

    • destaddr指標指向目標地址的結構.
    • 其他同send.

 

  • ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    • msghdr的結構定義如下:

      struct msghdr
      ...{
          void             *msg_name;         /**//* optional address */
          socklen_t    *msg_namelen;    /**//* address size in bytes */
          struct iovec *msg_iov;             /**//* array of I/O buffers */
          int                 msg_iovlen;        /**//* number of elements in array */
          void             *msg_control;      /**//* ancillary of data */
          socklen_t      msg_controllen; /**//* number of ancillary bytes */
          int                  msg_flags;         /**//* flags for received message */
          .
          .
          .
      };

    • 該函數指定多重緩衝取傳輸資料, 類似於writev.

 

2. 接收資料:

  • ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
    • flags可以是:
      • MSG_OOB: 如果協議支援, 接收帶外資料.
      • MSG_PEEK: 返回報文內容而不真正取走報文.
      • MSG_TRUNC: 即使報文被截斷, 返回的也是報文的實際長度.
      • MSG_WAITALL: 等待, 直到所有的資料可用(僅限SOCK_STREAM).

 

  • ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flags,

                                             struct sockaddr *restrict addr, socklen_t *restrict addrlen);

 

  • ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

 

3. 總結:

    函數sendto/recvfrom和函數send/recv很類似, 區別在於sendto/recvfrom允許在不需連線的socket上指定一個目標地址.

  • 對於連線導向的socket, 目標地址是忽略的, 因為目標地址已經包含在串連中了.
  • 對於不需連線的socket, 不能使用send/recv, 除非在調用connect時預先設定了目標地址. 否則, 需要使用sendto/recvfrom來完成報文的傳輸.

    這裡介紹了資料轉送的所有函數, 在socket系列文章的後面會有執行個體來調用這些函數.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.