epoll用法
# epoll解析
https://blog.csdn.net/armlinuxww/article/details/92803381 (opens new window)
ET和LT:
- Edge Triggered 边缘触发
- Level Triggered 水平触发
# tcp通信
https://blog.csdn.net/qq_31918961/article/details/80546537 (opens new window)
# git完整代码示例
https://gitee.com/colderleo/epoll-example-fork.git (opens new window)
# sin_addr网络地址转字符串
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
int main() {
printf("main start\n");
//设置sockaddr_in
sockaddr_in test_addr;
test_addr.sin_family = AF_INET; //IPV4
inet_pton(AF_INET, "192.168.0.2", &test_addr.sin_addr);
test_addr.sin_port = htons(9998);
//方法一: 通过inet_ntoa将sin_addr转换为字符串ip, 返回的是静态区的字符串指针。
printf("inet_ntoa convert sin_addr to ip_str: %s\n", inet_ntoa(test_addr.sin_addr) );
//方法二: 通过getnameinfo将sin_addr转换为字符串ip
char host_buf[NI_MAXHOST], port_buf[NI_MAXSERV];
int retval = getnameinfo((sockaddr*)&test_addr, sizeof(sockaddr_in), host_buf, sizeof(host_buf),
port_buf, sizeof(port_buf), NI_NUMERICHOST | NI_NUMERICSERV);
//NI_NUMERICHOST:返回数字形式的ip地址; NI_NUMERICSERV:返回数字形式的port
if(retval == 0) {
printf("getnameinfo convert sin_addr to ip_str: host=%s, port=%s\n", host_buf, port_buf);
} else {
printf("getnameinfo error: %s\n", gai_strerror(retval));
}
}
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
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
# 字符串/主机名转sin_addr网络地址
https://blog.csdn.net/kangear/article/details/8518048 (opens new window)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// inet_aton() 转换网络主机ipv4地址cp(如"192.168.1.10")为二进制数值,并存储在struct in_addr结构中,即第二个参数*inp,函数返回非0表示cp主机有地有效,返回0表示主机地址无效。
int inet_aton(const char *cp, struct in_addr *inp);
// inet_addr函数转换网络主机ipv4地址cp(如"192.168.1.10")为二进制数值并返回, 如果参数char *cp无效,函数返回-1(INADDR_NONE),这个函数在处理地址为255.255.255.255时也返回-1,255.255.255.255是一个有效的地址,不过inet_addr无法处理;
in_addr_t inet_addr(const char *cp);
int ret = inet_addr("192.168.1.10");
if (ret == INADDR_NONE) {
perror("inet_addr conver error");
}
//ip地址字符串转sin_addr
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(s_port));
if(inet_pton(AF_INET, argv_host, &server_addr.sin_addr) <= 0) { //如果是ipv6的地址,则用AF_INET6
perror("inet_pton error");
exit(-1);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# send和recv的返回值
https://blog.csdn.net/qq_26105397/article/details/80988429 (opens new window)
阻塞与非阻塞的send和recv返回值类似:
- <0 出错
- =0 对方调用了close API来关闭连接
0 接收到的数据大小,
返回值小于0时,如果 errno == EINTR, 表示被中断
在非阻塞的情况下, 如果 (errno == EAGAIN || errno == EWOULDBLOCK), 表示读完了或者写没空间(阻塞的情况下不可能收到这两个,因为会一直阻塞)
编辑 (opens new window)
上次更新: 2023/05/07, 17:27:54