Linux应用开发

Linux平台c语言应用开发

1. socket 网络编程与TCP

  • 主机字节序列和网络字节序列
    • 大端:高字节在低位,低字节在高位
    • 小端:高字节在高位,低字节在地位(x86架构多采用小端)
  • 网络规定使用大端字节序,所以也把大端字节序成为网络字节序列
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
uint32_t htonl(uint32_t hostlong); // 长整型的主机字节序转网络字节序
uint32_t ntohl(uint32_t netlong); // 长整型的网络字节序转主机字节序
uint16_t htons(uint16_t hostshort); // 短整形的主机字节序转网络字节序
uint16_t ntohs(uint16_t netshort); // 短整型的网络字节序转主机字节序

in_addr_t inet_addr(const char *cp); //字符串表示的 IPV4 地址转化为网络字节序
char* inet_ntoa(struct in_addr in); // IPV4 地址的网络字节序转化为字符串表示

//例程
void * server(void *argv){
int fd = socket(AF_INET, SOCK_STREAM, 0);
assert(fd != -1);
struct sockaddr_in serverAddr, cilentAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(6000);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

assert( bind(fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != -1);
assert( listen(fd, 5) != -1);
int len = sizeof(cilentAddr);
int res = accept(fd, (struct sockaddr *)&cilentAddr, &len);
assert(res != -1);
while (1)
{
char buff[128] = {0};
recv(res, buff, 127, 0);
printf("server recv:%s", buff);
if(strncmp(buff, "end", 3) == 0){
break;
}
send(res, "ok\n", 4, 0);
}
close(fd);
pthread_exit(NULL);
}
int main(){
pthread_t t;
pthread_create(&t, NULL, server, NULL);

int fd = socket(AF_INET, SOCK_STREAM, 0);
assert(fd != -1);
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(6000);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = connect(fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
assert(res != -1);
while (1)
{
char buff[128] = {0};
printf("input:");
fflush(stdout);
fgets(buff, 127, stdin);
send(fd, buff, strlen(buff), 0);
if(strncmp(buff, "end", 3) == 0){
break;
}
recv(fd, buff, 127, 0);
printf("cilent recv:%s", buff);
}
close(fd);
pthread_join(t, NULL);
exit(0);
}
  • 类似于与print,在tcp传输中同样存在数据缓冲区,在应用层只有一次接收,多次发送,但在传输层,发送端会在接收多次数据后通过数据缓冲区一次发送,而在接收端,在接收多次数据后全部放在tcp数据缓冲区
  • 由于数据缓冲区的存在,会产生粘包现象
  • netstat -natp 查看数据缓冲区
    • n 使用ip地址表示主机
    • a 显示结构包括监听socket
    • t 仅显示tcp连接
    • r 显示路由信息
    • i 显示网卡接口数据流量

2. strlen和sizeof

strlen 测量的是字符的实际长度,以’\0’ 结束(不包含’\0’ )。而sizeof 测量的是字符的分配大小,如果未分配大小,则遇到’\0’ 结束(包含’\0’ ,也就是strlen测量的长度加1),如果已经分配内存大小,返回的就是分配的内存大小。

3. UDP

  • tcp:面向连接、可靠的、流式服务
  • udp:无连接、不可靠、数据报