zoukankan      html  css  js  c++  java
  • 套接口和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

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

  • 相关阅读:
    什么样的代码称得上是好代码?
    九年程序人生 总结分享
    Docker入门 第一课 --.Net Core 使用Docker全程记录
    阿里云 Windows Server 2012 r2 部署asp.net mvc网站 平坑之旅
    Visual studio 2015 Community 安装过程中遇到问题的终极解决
    Activiti6.0 spring5 工作流引擎 java SSM流程审批 项目框架
    java 进销存 库存管理 销售报表 商户管理 springmvc SSM crm 项目
    Leetcode名企之路
    24. 两两交换链表中的节点
    21. 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/hanxi/p/2533868.html
Copyright © 2011-2022 走看看