总结:至少2个文件和共2条指令
我使用的文件是sock.h 和 wrapper.c
使用的指令是
$ gcc wrapper.c -o wrapper.o -c
$ gcc -shared -fPIC -o libnetlib.so wrapper.o
这样就生成了libnetlib.so文件了,将libnetlib.so复制到/lib中.
并将sock.h复制到/usr/include.即可使用
以后需要用到这个库函数的时候,添加这个库函数即可:
例如:
$gcc srv.c -o srv -lnetlib
$gcc cli.c -o cli -lnetlib
下面贴出sock.h 和wrapper.c 的代码:
sock.h:
#ifndef _SOCK_H__ #define _SOCK_H__ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <poll.h> #include <string.h> #include <strings.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> int Socket(int, int, int); int Inet_pton(int, const char *, void *); int Bind(int, const struct sockaddr *, socklen_t); int Listen(int, int); int Accept(int, struct sockaddr *, socklen_t *); int Connect(int, const struct sockaddr *, socklen_t); int Setsockopt(int, int, int, const void *, socklen_t); int TCP_listen(const char *, unsigned short, int, int *, struct sockaddr *, socklen_t *); int TCP_connect(const char *, const unsigned short); pid_t Fork(void); ssize_t Write(int, const void*, size_t); ssize_t Read(int, void*, size_t); #endif
wrapper.c:
#include "sock.h" #include <stdlib.h> #include <errno.h> int Socket(int domain, int type, int protocol) { int sockfd; sockfd = socket(domain, type, protocol); if(sockfd == -1){ perror("socket() error"); exit(0); } return sockfd; } int Inet_pton(int af, const char *src, void *dst) { int ret; ret = inet_pton(af, src, dst); if(ret != 1){ perror("inet_pton() error"); exit(0); } return ret; } int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { int ret; ret = bind(sockfd, addr, addrlen); if(ret != 0){ perror("bind() error"); exit(0); } return ret; } int Listen(int sockfd, int backlog) { int ret; ret = listen(sockfd, backlog); if(ret != 0){ perror("listen() error"); exit(0); } return ret; } int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { int connfd; connfd = accept(sockfd, addr, addrlen); if(connfd == -1){ perror("accept() error"); exit(0); } return connfd; } int Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { int ret; ret = connect(sockfd, addr, addrlen); if(ret != 0){ perror("connect() error"); exit(0); } return ret; } pid_t Fork(void) { pid_t pid; pid = fork(); if(pid < 0){ perror("fork() error"); exit(0); } return pid; } int Setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) { int ret; ret = setsockopt(sockfd, level, optname, optval, optlen); if(ret == -1){ perror("setsockopt() error"); printf("%d\n", errno); exit(1); } return ret; } int Getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) { if(getsockopt(sockfd, level, optname, optval, optlen) == 0) return 0; perror("getsockopt() error"); exit(1); } int TCP_connect(const char *ipaddr, const unsigned short port) { int sockfd; sockfd = Socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in srvaddr; bzero(&srvaddr, sizeof srvaddr); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(port); Inet_pton(AF_INET, ipaddr, &srvaddr.sin_addr); Connect(sockfd, (struct sockaddr *)&srvaddr, sizeof srvaddr); return sockfd; } int TCP_listen(const char *ipaddr, unsigned short port, int backlog, int *connfd, struct sockaddr *cliaddr, socklen_t *clilen) { int sockfd; sockfd = Socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in srvaddr; bzero(&srvaddr, sizeof srvaddr); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(port); if(ipaddr == NULL) srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); else Inet_pton(AF_INET, ipaddr, &srvaddr.sin_addr); Bind(sockfd, (struct sockaddr *)&srvaddr, sizeof srvaddr); Listen(sockfd, backlog); *connfd = Accept(sockfd, cliaddr, clilen); return sockfd; } ssize_t Read(int fd, void *buf, size_t count) { int nread; while((nread=read(fd, buf, count)) == -1 && errno == EINTR); if(nread == -1){ perror("read() error"); exit(1); } return nread; } ssize_t Write(int fd, const void *buf, size_t count) { ssize_t ret = 0, total = 0; while(count > 0){ while((ret=write(fd, buf+total, count)) == -1 && errno == EINTR); if(ret == -1){ perror("write() error"); exit(1); } count -= ret; total += ret; } return total; } /* int Poll(struct pollfd *client, nfds_t nfds, int timeout) { int nready; while(1){ nready = poll(client, nfds, timeout); if(nready == -1 && errno != EINTR){ perror("poll() error"); exit(0); } else if(nready == -1 && errno == EINTR) continue; else if(nready > 0) return nready; } } */ int Select(int nfds, fd_set *rset, fd_set *wset, fd_set *eset, struct timeval *timeout) { int ret; ret = select(nfds, rset, wset, eset, timeout); if(ret < 0){ perror("select() error"); exit(1); } return ret; }
cli.c:
#include "sock.h" #define MAXSIZE 100 int main(void) { int fd; fd = Socket(AF_INET, SOCK_STREAM, 0); // TCP socket struct sockaddr_in srvaddr; bzero(&srvaddr, sizeof srvaddr); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(50001); Inet_pton(AF_INET, "127.0.0.1", &srvaddr.sin_addr); Connect(fd, (struct sockaddr *)&srvaddr, sizeof srvaddr); char buf[MAXSIZE]; while(1) { bzero(buf, MAXSIZE); fgets(buf, MAXSIZE, stdin); write(fd, buf, strlen(buf)); } return 0; }
#include "sock.h" #define MAXSIZE 100 int main(void) { int fd; fd = Socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in srvaddr; bzero(&srvaddr, sizeof srvaddr); srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(50001); Inet_pton(AF_INET, "127.0.0.1", &srvaddr.sin_addr); Bind(fd, (struct sockaddr *)&srvaddr, sizeof srvaddr); Listen(fd, 5); int connfd = Accept(fd, NULL, NULL); char recv[MAXSIZE]; while(1) { bzero(recv, MAXSIZE); if(read(connfd, recv, MAXSIZE-1) <= 0) break; write(STDOUT_FILENO, recv, strlen(recv)); } return 0; }