首页 > 代码库 > 第十三章 守护进程和inetd超级服务器

第十三章 守护进程和inetd超级服务器

        书看到这里,我发现我应该把前面steven写的那些包裹函数之类的,实现出自己的一个库来,

方便每次调用,不用自己一遍一遍的写了。库就用libsock.so了。

  1. 先创建自己的头文件:unpv13.h

#ifndef UNPV13_H_
#define UNPV13_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MAXLINE 1024
#define LISTENQ 5
#define SERV_PORT 9999
int Tcp_connect(const char *host, const char *serv);
/* 其它的函数声明都放这,我这只放一个举例 */
#endif  //  UNPV13_H_

2. 创建自己的库函数,先来两个tcp_connect.c和tcp_listen.c

tcp_listen.c

#include "../include/unpv13.h"
int tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)
{
    int listenfd, n;
    const int on = 1;
    struct addrinfo hints, *res, *ressave;
    bzero(&hints, sizeof(hints));
    hints.ai_flags = AI_PASSIVE;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {
        printf("tcp_listen() error for %s, %s: %s\n", host, serv, gai_strerror(n));
        exit(1);
    }
    ressave = res;
    do {
        listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (listenfd < 0)
            continue;
        if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
            printf("tcp_listen() error: %s\n", strerror(errno));
            exit(1);
        }
        if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)
            break;
        close(listenfd);
    } while ((res = res->ai_next) != NULL);
    if (res == NULL) {
        printf("tcp_listen() error for %s, %s", host, serv);
        exit(1);
    }
    if (listen(listenfd, LISTENQ) < 0) {
        printf("tcp_listen() error: %s\n", strerror(errno));
        exit(1);
    }
    if (addrlenp)
        *addrlenp = res->ai_addrlen;
    freeaddrinfo(ressave);
    return (listenfd);
}
 
int Tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)

{

    return (tcp_listen(host, serv, addrlenp));

}


tcp_connect.c

#include "../include/unpv13.h"
int tcp_connect(const char *host, const char *serv)
{
    int sockfd, n;
    struct addrinfo hints, *res, *ressave;
    bzero(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {
        printf("getaddrinfo() error for %s, %s: %s\n", 
                host, serv, gai_strerror(n));
        exit(1);
    }
    ressave = res;
    do {
        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (sockfd < 0)
            continue;
        if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
            break;
        close(sockfd);
    } while ((res = res->ai_next) != NULL);
    if (res == NULL) {
        printf("tcp_connect() error for %s, %s\n", host, serv);
        exit(1);
    }
    freeaddrinfo(ressave);
    return (sockfd);
}
int Tcp_connect(const char *host, const char *serv)
{
    return (tcp_connect(host, serv));
}


3. 有了这两个文件后,我们把他们编译成共享库文件,也就是一般我们使用的.so文件

其实.so文件就是一堆.o文件打包差不多的效果,所以先来完成从.c文件转成.o文件,如下:

gcc -c tcp_listen.c

这样就生成了tcp_listen.o,同理:

gcc -c tcp_connect.c

这样就生成了tcp_connect.o

如何生成.so呢?

gcc -shared -fpic -o libsock.so tcp_listen.c tcp_connect.c

这样就生成了 libsock.so这个共享库

其实用开始生成的.o文件也可以这样操作

gcc -shared -fpic -o libsock.so tcp_listen.o tcp_connect.o

这样同样也能生成 libsock.so共享库,-shared是生成共享库的意思,-fpic是生成位置无关代码 -o指定生成的名

第十三章 守护进程和inetd超级服务器