• 套接口和I/O通信


      几个I/O相关的函数:

    #include <unistd.h>
    ssize_t read(int fd, void *buf, size_t count);
    ssize_t write(int fd, const void *buf, size_t count);
    int close(int fd);

      为了实现通信,fd可以是套接口(见linux的套接口和管道)的描述符。使用示例如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <time.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    
    #ifndef SHUT_WR
    #define SHUT_WR 1
    #endif
    
    int main()
    {
        int z;
        int s[2];
        char *msgp;
        int mlen;
        pid_t chpid;
        char buf[80];
        
        z = socketpair(AF_LOCAL,SOCK_STREAM,0,s);
        if (z==-1)
        {
            fprintf(stderr,"%s:socketpair(AF_LOCAL,SOCK_STREAM,0)\n",strerror(errno));
            exit(1);
        }
    
        //char *cp;
    
        //z=write(s[1],cp="Hello?",6);
        //printf("Wrote message '%s' on s[1]\n",cp);
        //z=read(s[0],buf,sizeof buf);
        //buf[z]=0;
        //printf("Received message '%s' from socket s[0]\n",buf);
    
        printf("s[0]=%d;\n",s[0]);
        printf("s[1]=%d;\n",s[1]);
    
    
        chpid = fork();
        if ( chpid == (pid_t)-1 )
        {
            fprintf(stderr,"%s:fork(2)\n",strerror(errno));
            exit(1);
        }
        else if (chpid==0)
        { 
            char rxbuf[80];
            printf("Parent PID is %ld\n",(long)getppid());
            close(s[0]);
            s[0]=-1;
    
            msgp="%Y-%m-%d %A %H:%M %P";
            mlen=strlen(msgp);
            printf("Child sending request '%s'\n",msgp);
            fflush(stdout);
            z=write(s[1],msgp,mlen);
            if (z<0)
            {
                fprintf(stderr,"%s:write(2)\n",strerror(errno));
                exit(1);
            }
            
        /*    if (shutdown(s[1],SHUT_WR)==-1)
            {
                fprintf(stderr,"%s:shutdown(2)\n",strerror(errno));
                exit(1);
            } 
    */
            z=read(s[1],rxbuf,sizeof rxbuf);
            if (z<0)
            {
                fprintf(stderr,"%s:read(2)\n",strerror(errno));
                exit(1);
            }
            rxbuf[z]=0;
            printf("Server returned '%s' \n",rxbuf);
            fflush(stdout);
            close(s[1]);
        }
        else
        {
            int status;
            char txbuf[80];
            time_t td;
            printf("Child PID is %ld\n",(long)chpid);
            fflush(stdout);
            close(s[1]);
            s[1]=-1;
            z=read(s[0],buf,sizeof buf);
            if (z<0)
            {
                fprintf(stderr,"%s:read(2)\n",strerror(errno));
                exit(1);
            }
            buf[z]=0;
            time(&td);
            strftime(txbuf,sizeof txbuf, buf, localtime(&td));
            z=write(s[0],txbuf,strlen(txbuf));
            if (z<0)
            {
                fprintf(stderr,"%s:write(2)\n",strerror(errno));
                exit(1);
            }
            close(s[0]);
            waitpid(chpid,&status,0);
        } 
        //system("netstat --unix -p");
    
        return 0;
    }

      例子有点长,

      //z=write(s[1],cp="Hello?",6);
        //printf("Wrote message '%s' on s[1]\n",cp);
      //z=read(s[0],buf,sizeof buf);
      //buf[z]=0;
    //printf("Received message '%s' from socket s[0]\n",buf);

       这一小段就实现了通信,我已经注释掉了,因为后面写的代码是一个获取服务器时间的代码。这一段代码就是从s[1]写数据,然后从s[0]读取数据。这点和管道是一样的。但是套接口的好处是还可以从s[0]写数据,从s[1]读数据。

      后面的大段代码中使用了shutdown函数,是用于关闭套接口的专用函数,关闭套接口优先使用shutdown函数而不是close函数。shutdown函数的原型:

    #include <sys/socket.h>
    int shutdown(int sockfd, int how);

      就是因为多了一个how选项,使得shutdown的功能多于close函数。how可以设置为:SHUT_RD, SHUT_WR, SHUT_RDWR。分别是代表关闭读,关闭写,关闭读写(等价于close)。

      为了获取服务器的时间符合需要的格式,还使用了strftime函数:

    #include <time.h>
    
    size_t strftime(char *s, size_t max, const char *format,
                    const struct tm *tm);

      参数介绍见:http://www.cppblog.com/gan/archive/2008/12/07/68788.html

      下一篇将介绍套接字的域和地址族

  • 相关阅读:
    如何成为强大的程序员?(转)
    PHP Directory 函数
    PHP 类相关函数
    myeclipse安装svn插件的多种方式
    PHPEXCEL类操作EXCEL
    PHP 自定义错误处理函数(转)
    JBoss JBPM 实践系列(一) 安装配置(Tomcat 6.0 + MySQL 5.1)
    Ext.data.Store的相关知识
    Lotus Notes 和 Crystal Report 的整合應用
    JBoss JBPM 实践系列(二) jbpm设计器的配置和使用
  • 原文地址:https://www.cnblogs.com/hanxi/p/2533868.html
Copyright © 2020-2023  润新知