Linux下C的网络编程

[TOC]

参考

Linux下

BS模式架构

基本函数

read()函数

1
ssize_t read(int fd, void *buf, size_t count)
  • fd => buf

write()函数

1
write(fd, buf, size)
  • buf => fd

fgets()函数

1
char *fgets(char *s, int size, FILE *stream)

获取键盘输入

  • stream => s

网络函数

socket函数

1
int socket(int domain, int type, int protocol);
  • domain:ipv4/ipv6
  • type:UDP/TCP
  • protocol:默认填写0
  • 返回服务器套接字描述符

服务器函数

bind函数

1
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd:服务器套接字文件描述符
  • *addr:服务器ip和端口信息
  • addrlen:服务器地址长度
  • 返回0成功,返回-1失败。

listen函数

1
listen(int sockfd, int backlog) // 激活套接字
  • backlog:连接请求的队列的最大长度,同时建立连接的最大值。

accept函数

1
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • sockfd:服务器套接字
  • addr:客户端地址信息。
  • addr_len:传入sizeof(addr)大小,返回真正接受到的客户端地址结构体大小。
  • 返回客户端文件描述符

客户端函数

connect函数

1
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
  • sockfd:客户端套接字
  • addr:服务器地址信息
  • addr_len:服务器地址结构体大小

一些细节

数据结构

1
2
3
4
5
6
7
8
struct sockaddr_in{
sa_family_t sin_family; // 16位地址类型
in_port_t sin_port; //16位端口号
struct in_addr sin_addr;
};
struct in_addr{
uint32_t s_addr; //32位ip地址
};

网络字节序

TCP/IP协议规定,网络数据流应采用大端字节序。如果发送主机是小端字节序,在把ip和端口号发送到缓冲区之前需要做字节序的转换。

1
2
3
4
uint32_t htonl(uint32_t hostlong);  //host to net long  服务器绑定IP
uint16_t htons(uint16_t hostshort); //host to net short 服务器绑定Port
int inet_pton(int af, const char *src, void *dst); //IP字符串=>网络字节序 客户端绑定服务器IP
int inet_ntop(int af, const void *src, char *dst, socklen_t size); //网络字节序=>IP字符串

tips

  • INADDR_ANY:不管数据是从哪个ip过来的,只是要绑定的端口号过来的数据,都可以接收到。这样方便用一个套接字来管理所有的ip。
  • 服务器accept时并不了解客户端地址的大小,因此传地址;而客户端connect时了解服务器端地址的大小,因此直接传值
  • 两端都是通过cfd来交流:服务器端accept得到cfd,客户端直接socket得到cfd。