学习笔记《实战Linux Socket编程》第一章

注:本文所有代码均运行在Ubuntu6.06上


第一章三个例子
///第一个例子/
//gcc p8.c
/*socketpair 使用范例*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>

int main(int argc, char *argv[])
{
    int z;
    int s[2];
   
    //生成本地套接口对
    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;
    }
   
    //报告所返回的套接口文件描述符
    printf("s[0] = %d;/n", s[0]);
    printf("s[1] = %d;/n", s[1]);
   
    system("netstat --unix -p");
   
    return 0;
}

///第二个例子/
//gcc p11.c
/*
在套接口上实现I/O示例
结论:套接口可以双向传送信息,面且套接口的关闭方式与文件相同
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
    int z;                //返回的状态码
    int s[2];            //套接口对
    char *cp;            //工作指针
    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));
        return 1;
    }
   
    //向套接口s[1]写入消息
    z = write(s[1], cp = "hello?", 6);
    if (z < 0)
    {
        fprintf(stderr, "%s:write(%d, /"%s/", %d)/n", strerror(errno), s[1], cp, strlen(cp));
        return 2;
    }
   
    printf("wrote message: '%s' on s[1]/n", cp);
   
    //向套接口s[0]读出消息
    z = read(s[0], buf, sizeof(buf));
    if (z < 0)
    {
        fprintf(stderr, "%s:read(%d, buf, %d)/n", strerror(errno), s[0], sizeof buf);
        return 3;
    }
   
    buf[z] = 0;
    printf("Received message '%s' from socket s[0]/n", buf);
   
    z = write(s[0], cp = "Go away!", 8);
    if (z < 0)
    {
        fprintf(stderr, "%s:write(%d, /"%s/", %d)/n", strerror(errno), s[0], cp, strlen(cp));
        return 4;
    }
   
    printf("Wrote message '%s' on s[0]/n", cp);
   
    z = read(s[1], buf, sizeof(buf));
    if (z < 0)
    {
        fprintf(stderr, "%s:read(%d, buf, %d)/n", strerror(errno), s[1], sizeof buf);
        return 3;
    }
   
    buf[z] = 0;
    printf("Received message '%s' from socket s[1]/n", buf);
   
    close(s[0]);
    close(s[1]);
   
    puts("Done.");
    return 0;
}



///第三个例子/
//gcc p18.c
/*
使用socketpair和fork的客户/服务器示例
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <errno.h>
#include <sys/wait.h>

//以下已在sys/socket.h中定义,但有的LINUX(如redhat6.0)没有定义
#ifndef SHUT_WR
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#endif

int main(int argc, char *argv[])
{
    int z;                //返回的状态码
    int s[2];            //套接口对
    char *msgp;        //消息指针
    int mlen;            //消息长度
    char buf[80];    //工作缓存区
    pid_t chpid;        //子进程PID
   
    //生成本地套接口对
    z = socketpair(AF_LOCAL, SOCK_STREAM, 0, s);
    if (z == -1)
    {
        fprintf(stderr, "%s:socketpair(2)/n", strerror(errno));
        exit(1);
    }
   
    //fork()调用后,生成两个进程
    if ((chpid = fork()) == (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[1]
        s[0] = -1;        //良好习惯
       
        //形成消息并记录长度
        //msgp = "%A %d-%b-%Y %l:%M %p";
        msgp = "%d-%b-%y";
        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]
        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);
    }
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值