@网络编程学习记录
网络编程学习笔记-基础
最近项目涉及网络编程,本文用以记录学习要点,方便日后查询相关内容。学习过程只要参考尹圣雨的《TCPIP网络编程》,本文中的内容和截图也大多来自此书。
一、 Linux文件操作
socket被视为文件的一种,网络编程中的数据传输同样使用文件I/O的相关函数。
1、打开文件
int open(const char* path, int flag);
成功返回文件描述符,失败返回-1;
path为文件名的字符串地址;
flag为文件打开模式,可选参数如下:
例子:
fd = open("data.txt", O_CREAT|O_WRONLY|O_TRUNC);
表明创建只能写的空文件,若已存在data.txt,则清空文件的全部数据。
2、关闭文件
int close(int fd);
成功回0,失败-1;
fd为文件描述符。
3、将数据写入文件
ssize_t write(int fd, const void* buf, size_t nbytes);
成功返回写入的字节数,失败返回-1;
fd :传输对象的文件描述符;
buf: 保存要传输数据的缓冲地址值;
nbytes:要传输数据的字节数。
4、从文件读取数据
ssize_t read(int fd, void* buf, size_t nbytes);
成功返回接受的字节数,回0则表明遇到文件结尾,失败回-1;
fd :接受对象的文件描述符;
buf: 要保存的接受数据的缓冲地址值;
nbytes:要接受数据的最大字节数。
二、网络编程框架
1、socket函数
创建socket的函数:
int socket(int domain, int type, int protocol);
成功返回文件描述符,失败返回-1;
domain指协议族(Protocol Family)信息,最常见的:
PF_INET : IPv4;
PF_INET6 : IPv6;
type指套间字类型:
TCP: SOCK_STREAM;
UDP: SOCK_DGRAM;
协议最终选择:
对于大多数协议,当确认来前两个参数即协议族和套间字类型后,其协议也就确定下来了,第三个参数可以直接传递0;
除非在同一协议族中存在有多个传输方式相同的协议。
举例:
创建IPv4中面向连接的套间字
int tcp_socket = socket(PF_INET, SOCK_STREAM, 0);
或
int tcp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
2、bind函数
int bind(int sockfd, struct sockaddr* myaddr, socklen_t addrlen);
// 成功返回0,失败-1;
先用sockaddr_in存储IPv4相关的地址、端口等信息,再将这些信息赋值给sockaddr结构体作为bind等函数的参数。
sockaddr_in的结构体表示如下:
sockaddr的结构体表示为:
struct sockaddr
{
sa_family_t sin_family; //地址族信息
char sa_data[14]; //地址信息
};
sockaddr_in只针对IPv4,而sockaddr并非只针对IPv4,所以sa_data后面几位也都是0,在声明sockaddr_in应使用memset将sockaddr_in的初始值设置成0。
以下给出一个服务器端常见套间字的初始化过程:
in_addr_t inet_addr(const char* string);
成功返回满足网络字节序的32位整型(即不需要再调用htonl()函数进行字节序的转换),失败返回INADDR_NONE。
3、listen函数
int listen(int sockfd, int backlog);
成功0,失败-1;
backlog为请求等待队列的长度,表示使最多backlog个连接请求进入队列;
只有服务器调用listen函数,客户端才能调用connect函数,提前调用会出错。
4、accept函数
int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
成功回文件描述符,失败回-1;
sockfd为服务器套间字的文件描述符;
addr为保存发起连接请求的客户端地址信息的变量地址值;
addrlen为用来保存第二个参数addr结构体长度的变量地址;
调用accept的过程可以自动生成用于数据传输的套接字。
5、connect函数
int connect(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
成功回0,失败回-1;
sockfd表示客户端套接字文件描述符;
addr表示保存目标服务器端地址信息的变量地址值;
addrlen为用来保存第二个参数addr结构体长度的变量地址;
connect函数只有在服务器端接受连接请求或发送断网等异常情况而中断连接请求时才会完成函数调用。
注意:客户端ip地址和端口号在调用connect函数时自动分配,无需调用标记的bind函数进行分配。
6、函数调用框架
服务器端:
客户端:
相互间的关系: