套接口和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

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

posted @ 2012-06-04 09:11  涵曦  阅读(620)  评论(0编辑  收藏  举报