Skip to content

Commit 7e977f3

Browse files
committed
4. 代码清单5-12 访问daytime服务
1 parent eb416c9 commit 7e977f3

File tree

6 files changed

+116
-2
lines changed

6 files changed

+116
-2
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <sys/socket.h>
2+
#include <sys/types.h>
3+
#include <netinet/in.h>
4+
#include <arpa/inet.h>
5+
#include <assert.h>
6+
#include <stdio.h>
7+
#include <unistd.h>
8+
#include <netdb.h>
9+
10+
int main(int argc, char* argv[]) {
11+
12+
// 检测参数个数
13+
if(argc != 2) {
14+
printf("Wrong number of parameters.\n");
15+
return 1;
16+
}
17+
18+
char* hostname = argv[1];
19+
20+
// 通过主机名获取主机信息
21+
struct hostent* hostinfo = gethostbyname(hostname);
22+
assert(hostinfo);
23+
24+
// 通过服务名搜索服务
25+
struct servent* servinfo = getservbyname("daytime", "tcp");
26+
assert(servinfo);
27+
printf("the daytime port is %d\n", ntohs(servinfo -> s_port));
28+
29+
// 设定地址信息
30+
struct sockaddr_in address;
31+
address.sin_family = AF_INET;
32+
address.sin_port = servinfo -> s_port;
33+
address.sin_addr = *(struct in_addr*)* hostinfo -> h_addr_list;
34+
35+
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
36+
int result = connect(sockfd, (struct sockaddr*)&address, sizeof(address));
37+
assert(result != -1);
38+
39+
char buffer[128];
40+
result = read(sockfd, buffer, sizeof(buffer));
41+
assert(result > 0);
42+
buffer[result] = '\0';
43+
44+
printf("the day time is: %s\n", buffer);
45+
close(sockfd);
46+
return 0;
47+
}

README.md

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Linux高性能服务器编程读书记录
2+
title: Linux高性能服务器编程记录
33

44
---
55
开头选了这本书, 看到这本书是他人总结三大本后自己写的, 先求个理解大概.
@@ -11,9 +11,13 @@ title: Linux高性能服务器编程读书记录
1111
# demo 记录
1212

1313
2019年8月20日 编写demo <1. 客户端自动发送固定信息> -- 所用基础连接部分和TCP连接部分
14+
1415
2019年8月22日 编写demo <2. 伪全双工TCP> -- 所用截止到网络Api之前
16+
1517
2019年8月22日 编写demo <3. 伪全双工UDP> -- 所用截止到网络Api之前
1618

19+
2019年8月25日 复现 源码 <4. 代码清单5-12 访问daytime服务> -- 第五章结束
20+
1721
## 客户端自动发送固定信息
1822

1923
## 伪全双工TCP
@@ -302,10 +306,73 @@ struct linger {
302306
```
303307
#### 网络信息API
304308
```c
309+
#include <netdb.h>
310+
// 通过主机名查找ip
311+
struct hostent* gethostbyname(const char* name);
312+
313+
// 通过ip获取主机完整信息
314+
// type为IP地址类型 AF_INET和AF_INET6
315+
struct hostent* gethostbyaddr(const void* addr, size_t len, int type);
316+
317+
struct hostent {
318+
char* h_name;
319+
char ** h_aliases;
320+
int h_addrtype;
321+
int h_length;
322+
char** h_addr_list; /* 按网络字节序列出主机IP地址列表*/
323+
}
324+
```
325+
以下两个函数通过读取/etc/services文件 来获取服务信息
326+
```c
327+
#include <netdb.h>
328+
// 根据名称获取某个服务的完整信息
329+
struct servent getservbyname(const char* name, const char* proto);
330+
331+
// 根据端口号获取服务信息
332+
struct servent getservbyport(int port, const char* proto);
333+
334+
struct servent {
335+
char* s_name; /* 服务名称*/
336+
char ** s_aliases; /* 服务的别名列表*/
337+
int s_port; /* 端口号*/
338+
char* s_proto; /* 服务类型, 通常为TCP或UDP*/
339+
}
340+
```
341+
```c
342+
#include <netdb.h>
343+
// 内部使用的gethostbyname 和 getserverbyname
344+
// hostname 用于接收主机名, 也可以用来接收字符串表示的IP地址(点分十进制, 十六进制字符串)
345+
// service 用于接收服务名, 字符串表示的十进制端口号
346+
// hints参数 对getaddrinfo的输出进行更准确的控制, 可以设置为NULL, 允许反馈各种有用的结果
347+
// result 指向一个链表, 用于存储getaddrinfo的反馈结果
348+
int getaddrinfo(const char* hostname, const char* service, const struct addrinfo* hints, struct addrinfo** result)
349+
350+
struct addrinfo{
351+
int ai_flags;
352+
int ai_family;
353+
int ai_socktype; /* 服务类型, SOCK_STREAM或者SOCK_DGRAM*/
354+
int ai_protocol;
355+
socklen_t ai_addrlen;
356+
char* ai_canonname; /* 主机的别名*/
357+
struct sockaddr* ai_addr; /* 指向socket地址*/
358+
struct addrinfo* ai_next; /* 指向下一个结构体*/
359+
}
305360

361+
// 需要手动的释放堆内存
362+
void freeaddrinfo(struct addrinfo* res);
306363
```
364+
![](https://ftp.bmp.ovh/imgs/2019/08/7ebedb14d8eedeac.png)
307365
308-
![](Linux高性能服务器编程读书记录/socket选项.jpg)
366+
```c
367+
#include <netdb.h>
368+
// host 存储返回的主机名
369+
// serv存储返回的服务名
370+
371+
int getnameinfo(const struct sockaddr* sockaddr, socklen_t addrlen, char* host, socklen_t hostlen, char* serv
372+
socklen_t servlen, int flags);
373+
374+
```
375+
![](https://ftp.bmp.ovh/imgs/2019/08/bc7196e9a30d5152.png)
309376

310377
测试
311378
使用

0 commit comments

Comments
 (0)