UNP练习:TCP时间获取程序

《UNIX 网络编程:卷1》学习记录1:

书本上有两个程序:

  • 1.2节:简单的 TCP 时间获取客户程序
  • 1.5节:简单的 TCP 时间获取服务器程序

本文记录的是我在学习过程编写的 C++ 版本的程序(但其实还是 C 程序,hahaha…),为了熟悉 UNIX 函数库,这里并没有基于书中的 <unp.h> 头文件来编写,而是全部自己添加 C 函数库中的头文件。程序如下:

简单的 TCP 时间获取客户程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>

#define MAXLINE 4096

using namespace std;

int main(int argc, char **argv){
int sockfd, n;
char recevline[MAXLINE + 1];

// sockaddr_in结构定义在<netinet/in.h>头文件中
struct sockaddr_in servaddr;

if (argc != 3){
cerr << "usage: " << argv[0] << " <IPaddress> <port>" << endl;
return 0;
}

//socket()在<sys/socket.h>
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
cerr << "socket error" << endl;
return 0;
}

bzero(&servaddr, sizeof(servaddr)); //定义在<string.h>头文件中
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2])); //头文件<arpa/inet.h>

//inet_pton()在头文件<arpa/inet.h>
if ( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0 ){
cerr << "inet_pton error for " << argv[1] << endl;
return 0;
}

if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){
cerr << "connect error" << endl;
return 0;
}

while ( (n = read(sockfd, recevline, MAXLINE)) > 0 ){ //头文件<unisted.h>
recevline[n] = 0;
if ( fputs(recevline, stdout) == EOF ){ //头文件<stdio.h>
cerr << "fputs error" << endl;
return 0;
}
}
if ( n < 0 ){
cerr << "read error" << endl;
return 0;
}

return 0;
}
简单的 TCP 时间获取服务器程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>

#define MAXLINE 4096
#define LISTENQ 1024

using namespace std;


int main(int argc, char **argv){
int listenfd, connfd;
struct sockaddr_in servaddr; // sockaddr_in结构定义在<netinet/in.h>头文件中
char buff[MAXLINE];
time_t ticks;

if (argc != 2){
cerr << "usage: " << argv[0] << " <listen_port>" << endl;
return 0;
}

if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
cerr << "socket error" << endl;
return 0;
}

bzero(&servaddr, sizeof(servaddr)); //定义在<string.h>头文件中
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //头文件<arpa/inet.h>
servaddr.sin_port = htons(atoi(argv[1])); //头文件<arpa/inet.h>

//bind()在头文件<sys/socket.h>中
if ( bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 ){
cerr << "bind error" << endl;
return 0;
}

if (listen(listenfd, LISTENQ) < 0){ //头文件<sys/socket.h>
cerr << "listen error" << endl;
return 0;
}

for (;;){
if ((connfd = accept(listenfd, (struct sockaddr *) NULL, NULL)) < 0){
cerr << "accept error" << endl;
return 0;
}
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));//c头文件<stdio.h> 或c++头文件<cstdlib>
if ( write(connfd, buff, strlen(buff)) < 0 ){ //头文件<unisted>
cerr << "write error" << endl;
return 0;
}

if (close(connfd) < 0){ //头文件<unisted>
cerr << "close error" << endl;
return 0;
}
}

return 0;
}