第15章 Unix域协议

#include <sys/un.h>

struct sockaddr_un
{
sa_family_t  sun_family;    /*  AF_LOCAL  */
char         sun_path[104]; /*可能是92~108*/
};

#include <sys/socket.h>

//创建两个连接起来的Unix域套接字
int socketpair(int family/*AF_LOCAL*/, int type, int protocol/*0*/, int sockfd[2]);//SOCK_STREAM创建全双工的流管道

Unix域字节流客户端

#include "../Gnet.h"

void do_client(int connfd)
{
    char buf[MAX_LINE];

    while(fgets(buf, MAX_LINE, stdin) != NULL)
    {
        Write(connfd, buf, strlen(buf));
        memset(buf, 0, MAX_LINE);
        if(Read(connfd, buf, MAX_LINE) == 0)
            perr_exit("server terminated.\n");
        fputs(buf, stdout);
    }
}

int main(int argc, const char* argv[])
{
    int connfd;
    struct sockaddr_un server_addr;

    connfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sun_family = AF_LOCAL;
    strcpy(server_addr.sun_path, LOCAL_STRPATH);
    Connect(connfd, (struct sockaddr*)&server_addr, sizeof(server_addr));

    do_client(connfd);

    return 0;
}

Unix字节流服务器

#include "../Gnet.h"

void do_server(int connfd)
{
    ssize_t nread;
    char buf[MAX_LINE];

    while((nread = Read(connfd, buf, MAX_LINE)) > 0)
        Write(connfd, buf, nread);
}

void sig_child(int signo)
{
    pid_t pid;
    int stat;

    printf("in sig_child.\n");
    while((pid = waitpid(-1,&stat, WNOHANG)) > 0)
        printf("child %d terminated\n", pid);
    printf("out sig_child.\n");
}

int main(int argc, const char* argv[])
{
    int lfd, connfd;
    struct sockaddr_un server_addr, client_addr;
    socklen_t client_addr_len;
    pid_t child_id;

    struct sigaction sigaction_set, sigaction_get;
    sigaction_set.sa_handler = sig_child;
    sigemptyset(&sigaction_set.sa_mask);
    sigaction_set.sa_flags = 0;
    if(sigaction(SIGCHLD, &sigaction_set, &sigaction_get) <0)
        printf("sigaction(SIGCHLD) error!\n");

    memset(&server_addr, 0, sizeof(server_addr));
    unlink(LOCAL_STRPATH);//bind之前删除路径名
    server_addr.sun_family = AF_LOCAL;
    strcpy(server_addr.sun_path, LOCAL_STRPATH);

    lfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
    Bind(lfd, (const struct sockaddr*)&server_addr, sizeof(server_addr));
    Listen(lfd, LISTENQ);

    while(1)
    {
        client_addr_len = sizeof(client_addr_len);
        connfd = Accept(lfd, (struct sockaddr*)&client_addr, &client_addr_len);

        if((child_id = fork()) == 0)//子进程
        {
            Close(lfd);
            do_server(connfd);
            Close(connfd);
            exit(0);
        }
        else//父进程
        {
            printf("child %d connected\n", child_id);
            Close(connfd);
        }
    }

    return 0;
}

Unix域数据报客户端

#include "../Gnet.h"

void do_client(int udpfd, struct sockaddr* pserver_addr, socklen_t server_addr_len)
{
    char buf[MAX_LINE];
    int nread;

    while(fgets(buf, MAX_LINE, stdin) != NULL)
    {
        sendto(udpfd, buf, strlen(buf), 0, pserver_addr, server_addr_len);
        nread = recvfrom(udpfd, buf, MAX_LINE, 0, NULL, NULL);
        fputs(buf, stdout);
    }
}

int main(int argc, const char* argv[])
{
    int sockfd;
    struct sockaddr_un server_addr, client_addr;

    sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);
    memset(&client_addr, 0, sizeof(client_addr));
    client_addr.sun_family = AF_LOCAL;
    strcpy(client_addr.sun_path, tmpnam(NULL));
    Bind(sockfd, (struct sockaddr*)&client_addr, sizeof(client_addr));

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sun_family = AF_LOCAL;
    strcpy(server_addr.sun_path, LOCAL_STRPATH);

    do_client(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));

    return 0;
}

Unix域数据报服务器

#include "../Gnet.h"

void do_server(int udpfd)
{
    ssize_t nread;
    char buf[MAX_LINE];
    struct sockaddr_un client_addr;
    socklen_t client_addr_len;

    while(1)
    {
        client_addr_len = sizeof(client_addr);
        nread = recvfrom(udpfd, buf, MAX_LINE, 0, (struct sockaddr*)&client_addr, &client_addr_len);
        sendto(udpfd, buf, nread, 0, (struct sockaddr*)&client_addr, client_addr_len);
    }
}

int main(int argc, const char* argv[])
{
    int udpfd;
    struct sockaddr_un server_addr;

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sun_family = AF_LOCAL;
    strcpy(server_addr.sun_path, LOCAL_STRPATH);

    udpfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);
    unlink(LOCAL_STRPATH);
    Bind(udpfd, (const struct sockaddr*)&server_addr, sizeof(server_addr));
    printf("waiting for connecting.\n");

    do_server(udpfd);

    return 0;
}

github:https://github.com/gongluck/unp-notes

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏乐沙弥的世界

RAC环境下的阻塞(blocking blocked)

      RAC环境下的阻塞不同于单实例情形,因为我们需要考虑到位于不同实例的session。也就是说之前查询的v$session,v$lock相应的应变化为...

862
来自专栏数据库新发现

关于shared pool的深入探讨(五)

http://www.eygle.com/internal/shared_pool-5.htm

792
来自专栏xingoo, 一个梦想做发明家的程序员

WSAEventSelect模型 ---应用实例,重写TCP服务器实例

// WSAEvent.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <winsock2.h> #...

1789
来自专栏乐沙弥的世界

Oracle 11g RAC CRS-4535/ORA-15077

    新安装了Oracle 11g rac之后,不知道是什么原因导致第二个节点上的crsd无法启动?其错误消息是CRS-4535: Cannot commun...

593
来自专栏杨建荣的学习笔记

impdp异常中断导致的问题(r2第8天)

今天查看数据库的负载,发现cpu消耗异常的高。里面有不少dw的进程.但是查看impdp的进程却不存在。 查看datapump的进程情况,发现大量的job,但是状...

36311
来自专栏乐沙弥的世界

CRS-1006 , CRS-0215 故障一例

    安装好sles 10 sp3 + Oracle 10g RAC之后,在配置监听器时,总是提示主机bo2dbp上的监听服务已经在运行,忽略错误之后手动在b...

463
来自专栏乐沙弥的世界

ORA-19815,ORA-19809 :limit exceeded for recovery files

    数据库重新启动的时候,收到了ORA-19815的错误。从错误的提示来看,是由于闪回区的空间被填满导致无法成功启动。这种情形我们通常考虑的是清除归档日志,...

583
来自专栏乐沙弥的世界

RAC 环境下修改归档模式

    RAC环境下的归档模式切换与单实例稍有不同,主要是共享存储所产生的差异。在这种情况下,我们可以将RAC数据库切换到非集群状态下,仅仅在一个实例上来实施归...

812
来自专栏乐沙弥的世界

配置客户端连接到ASM实例

   对于Oracle 网络配置,我们通常通过negmgr或者netca来完成客户端连接到数据库实例。而对于连接到ASM实例,同样可以实现从客户端来进行连接。不...

644
来自专栏杨建荣的学习笔记

使用strace分析exp的奇怪问题(r3笔记第41天)

exp算是一个经典的数据导出工具了。对于小数量的表来说,个人还是比较钟爱exp。毕竟expdp还需要配置directory而且还在服务端。exp在数据量小的情况...

3548

扫码关注云+社区