今天开始拜读《Unix网络编程》。找到的源代码在Linux下有各种问题,最后决定还是自己从头写比较好。
从第一个时间服务程序开始学习。今天先看一下主要的头文件的作用。
在common.h中(参照 unp.h 自己写的,包含常用头文件和一些常量定义,用着方便),有以下的头文件:
sys/types.h
此头文件是系统类型的定义,如:int8_t int16_t int32_t int64_t等等
sys/socket.h
这是socket的接口,在其中引入bits/socket.h,其中定义了各种常量。
netinet/in.h
定义了各种地址结构体和常量。
arpa/inet.h
定义了地址转换的函数。
其它的头文件是常用头文件。还有一些常数定义以及结构体的简称。以后会随时添加。
在error.c和error.h中,声明和定义了常用的错误输出。
目录结构为下图所示:
以下是源程序:
daytimecpcli.c:
#include "common.h" #include "error.h" int main(int argc, char **argv) { int sockfd, n; char recvline[MAXLINE + 1]; struct sockaddr_in servaddr; if (argc != 2) err_quit("usage: ./daytimecpcli.c <IP address>"); if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err_sys("socket error"); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(IPPORT_DAYTIME); if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) err_quit("inet_pton error for %s", argv[1]); if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) err_sys("connect error"); while ((n = read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; if (fputs(recvline, stdout) == EOF) err_sys("fputs error"); } if (n < 0) err_sys("read error"); exit(0); }common.h:
#ifndef __COMMON_H #define __COMMON_H #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define MAXLINE 4096 #define SA struct sockaddr #endif
#ifndef __MYERROR_H #define __MYERROR_H #include <stdio.h> #include <stdlib.h> void err_ret(const char *fmt, ...); void err_sys(const char *fmt, ...); void err_dump(const char *fmt, ...); void err_msg(const char *fmt, ...); void err_quit(const char *fmt, ...); #endif
#include <errno.h> /* for definition of errno */ #include <stdarg.h> /* ANSI C header file */ #include "error.h" #include "common.h" static void err_doit(int, const char *, va_list); void err_ret(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, fmt, ap); va_end(ap); return; } void err_sys(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, fmt, ap); va_end(ap); exit(1); } void err_dump(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, fmt, ap); va_end(ap); abort(); exit(1); } void err_quit(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(0, fmt, ap); va_end(ap); exit(1); } void err_msg(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(0, fmt, ap); va_end(ap); return; } static void err_doit(int errnoflag, const char *fmt, va_list ap) { int errno_save; char buf[MAXLINE]; errno_save = errno; vsprintf(buf, fmt, ap); if (errnoflag) sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); strcat(buf, "\n"); fflush(stdout); fputs(buf, stderr); fflush(stderr); return; }
all: liberr.a liberr.a: liberr.o ar rv liberr.a liberr.o liberr.o: error.c error.h common.h gcc error.c -c -o liberr.o clean: rm -rf *.o *.a
targets = daytimecpcli cc = gcc INCLUDES = -I"../sock/" LIBS = -L"../sock/" all: $(targets) daytimecpcli: daytimecpcli.c ../sock/liberr.a $(cc) -o daytimecpcli daytimecpcli.c $(LIBS) -lerr $(INCLUDES) ../sock/liberr.a: ../sock/error.c ../sock/error.h ../sock/common.h cd ../sock && make clean: rm -rf $(targets) *.o
原文地址:http://blog.csdn.net/pdcxs007/article/details/43735975