天天看點

socketpair的使用

socketpair函數概要例如以下:

#include <sys/types.h>

#include <sys/socket.h>

int socketpair(int domain, int type, int protocol, int sv[2]);

sys/types.h檔案須要用來定義一些C宏常量。sys/socket.h檔案必須包括進來定義socketpair函數原型。

socketpair函數須要四個參數。他們是:

套接口的域

套接口類型

使用的協定

指向存儲檔案描寫叙述符的指針

類型參數聲明了我們希望建立哪種類型的套接口。socketpair函數的選擇例如以下:

SOCK_STREAM

SOCK_DGRAM

對于socketpair函數,protocol參數必須提供為0。

參數sv[2]是接收代表兩個套接口的整數數組。每個檔案描寫叙述符代表一個套接口,而且與還有一個并沒有差别。

假設函數成功,将會傳回0值。否則将會傳回-1表明建立失敗,而且errno來表明特定的錯誤号。

關于流程。socketpair()函數建立出兩個程序,fork()之後這兩個程序都會運作主程式中的代碼,這個一定要注意!尤其是bind的時候,假設bind兩次的話,那就會出錯了。通常會在子程序裡調用一個帶死循環的函數,這樣就好了。(這個情況的樣例會在綜合運用中解說)

一下給出個簡單的樣例。

// 建立socket對

       #include <sys/types.h>

       #include <sys/socket.h>

       #include <stdlib.h>

       #include <stdio.h>

       int main ()

       {

         int fd[2];

        int r = socketpair( AF_UNIX, SOCK_STREAM, 0, fd );

        if ( r < 0 ) {

          perror( "socketpair()" );

          exit( 1 );

        }

        if ( fork() ) {

          /* Parent process: echo client */

          int val = 0;

          close( fd[1] );

          while ( 1 ) {

            sleep( 1 );

            ++val;

            printf( "Sending data: %d/n", val );

            write( fd[0], &val, sizeof(val) );

            read( fd[0], &val, sizeof(val) );

            printf( "Data received: %d/n", val );

          }

        else {

          /* Child process: echo server */

          int val;

          close( fd[0] );

            read( fd[1], &val, sizeof(val) );

            write( fd[1], &val, sizeof(val) );

      }

在給出一個用sendmsg來傳遞資料的樣例

/*****************************************

 *

 * Listing 1.2

 * Example performing I/O on s socket pair:

 *

 * ******************************************/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#include <string.h>

int main(int argc,char **argv)

{

    int z;        /* Status return code */

    int s[2];    /* Pair of sockets */

 struct msghdr msg;

    struct iovec iov[1];

 char send_buf[100] = "TEST";

 struct msghdr msgr;

    struct iovec iovr[1];

    char recv_buf[100];

    /*

     * Create a pair of local sockets:

     */

    z = socketpair(AF_LOCAL,SOCK_STREAM,0,s);

    if(z == -1)

    {

        fprintf(stderr,

                "%s:socketpair(AF_LOCAL,SOCK_STREAM,""0)/n",strerror(errno));

        return 1;    /* Failed */

    }

     * Sendmsg s[1]:

         bzero(&msg, sizeof(msg));

         msg.msg_name = NULL;        /* attention this is a pointer to void* type */

         msg.msg_namelen = 0;

         iov[0].iov_base = send_buf;

         iov[0].iov_len = sizeof(send_buf);

         msg.msg_iov = iov;

         msg.msg_iovlen = 1;

    printf("sendmsg begin./n");

   z = sendmsg( s[1], &msg, 0 );

   if(z == -1 )

   {

    fprintf(stderr,"Sendmsg failed.  errno : %s/n",strerror(errno));

    return -1;

   }

    printf("Sendmsg Success!/n");

     * Read from socket s[0]:

         msgr.msg_name = NULL;        /* attention this is a pointer to void* type */

         msgr.msg_namelen = 0;

         iovr[0].iov_base = &recv_buf;

         iovr[0].iov_len = sizeof(recv_buf);

         msgr.msg_iov = iovr;

         msgr.msg_iovlen = 1;

         z = recvmsg(  s[0], &msgr, 0);

    fprintf(stderr,"Recvmsg failed.  errno : %s/n",strerror(errno));

    printf("Recvmsg Success!/n");

 printf("recvmsg : %s/n", recv_buf);

     * Close the sockets:

    close(s[0]);

    close(s[1]);

    puts("Done");

    return 0;

}