书看到这里,我发现我应该把前面steven写的那些包裹函数之类的,实现出自己的一个库来,
方便每次调用,不用自己一遍一遍的写了。库就用libsock.so了。
先创建自己的头文件: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指定生成的名