TCP/IP网络编程C01-理解网络编程和套接字

学习笔记

网络编程(套接字编程)就是编写程序使两台联网的计算机互相交换数据,而套接字就是用来连接网络的工具。

服务器端套接字

#include <sys/socket.h>
int socket(int domain, int type, int protocol);       
// 功能:创建套接字。
// 参数:domain:采取的协议族,一般为 PF_INET;type:数据传输方式,一般为 SOCK_STREAM;protocol:一般设为 0 即可。
// 返回值:成功时返回文件描述符,失败时返回 -1
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);  
// 功能:为套接字分配地址信息。
// 参数:sockfd:要分配地址信息的套接字文件描述符;myaddr:存有地址信息的结构体变量指针;addrlen:第二个参数的长度。
// 返回值:成功时返回 0,失败时返回 -1
int listen(int sockfd, int backlog);  
// 功能:将套接字转换为可接收连接的状态。
// 参数:sock:希望进入等待连接请求状态的套接字文件描述符;backlog:连接请求等待队列的长度,最多使 backlog 个连接请求进入队列。
// 返回值:成功时返回 0,失败时返回 -1
int accept(int sockfd, struct sockaddr *addr, socklen_t addrlen);  
// 功能:受理连接请求等待队列中待处理的连接请求。
// 参数:sock:服务器套接字的文件描述符;addr:用于保存发起连接请求的客户端地址信息;addrlen:第二个参数的长度。
// 返回值:成功时返回创建的套接字文件描述符,失败时返回 -1

接受连接请求的服务器端套接字编程流程:

  1. 调用 socket 函数创建套接字;

  2. 调用 bind 函数为套接字分配 IP 地址与端口号;

  3. 调用 listen 函数将套接字转换为可接收状态;

  4. 调用 accept 函数受理连接请求。accept 会阻塞,直到有连接请求才会返回;

  5. 调用 read/write 函数进行数据交换;

  6. 调用 close 函数断开连接;

客户端套接字

#include <sys/socket.h>
int connect(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen);  
// 功能:请求连接。
// 参数:sock:客户端套接字的文件描述符;serv_addr:保存目标服务器端地址信息的结构体指针;addrlen:第二个参数的长度(单位是字节)
// 返回值:成功时返回 0,失败时返回 -1

客户端请求连接步骤:

  1. 调用 socket 函数创建套接字;

  2. 调用 connect 函数请求连接;

  3. 调用 read/write 函数进行数据交换;

  4. 调用 close 函数断开连接;

客户端的 IP 地址和端口在调用 connect 函数时自动分配,无需调用 bind 函数。

基于Linux的文件操作

//file descriptor

#include<fcntl.h>       // fcntl.h 和 unistd.h 包含的内容有些相似,包括 open 函数等。总之使用文件函数时将 fcntl.h 和 unistd.h 都 include 就可以了
#include<unistd.h>
int open(const char *path, int flag);                   
// 功能:按 flag 指定的模式打开文件。
// 参数:path:文件名的地址;flag:文件打开的模式。
// 返回值:成功时返回文件描述符,失败时返回 -1
int close(int fd);
// 功能:关闭 fd 对应的文件或套接字。当关闭一个套接字时会向对方发送 EOF。
// 参数:fd:文件或套接字的文件描述符。
// 返回值:成功时返回 0,失败时返回 -1
ssize_t read(int fd, void* buf, size_t nbytes);  
// 功能:从文件 fd 读取数据。read 函数会阻塞,直到读取到数据或 EOF 才返回。
// 参数:fd:文件描述符;buf:保存要接收的数据;nbytes:要接收的最大字节数。
// 返回值:成功时返回接收的字节数(遇到文件尾则返回 0),失败时返回 -1
ssize_t write(int fd, const void* buf, size_t nbytes);  
// 功能:向文件 fd 输出数据。
// 参数:fd:文件描述符;buf:要传输的数据;nbytes:要传输的字节数。
// 返回值:成功时返回写入的字节数,失败时返回 -1

EOF 即表示文件尾。

size_t 的类型是 unsigned int,ssize_t 的类型是 signed int。

文件描述符 (文件句柄)

  • Linux 中套接字描述符也是文件,因此通过套接字发送、接收数据就和读写文件一样,通过 read、write 这些函数来接收、发送数据。
  • 文件描述符是系统分配给文件或套接字的整数。
  • 0、1、2 分别由系统分配给了标准输入、标准输出和标准错误。
  • 文件和套接字创建时才会被分配文件描述符。它们的文件描述符会从 3 开始按序递增。
  • Windows 系统中术语”句柄“和 Linux 中的文件描述符含义相同。
文件描述符 对象
0 标准输入:Standard Input
1 标准输出:Standard Output
2 标准错误:Standard Error

文件打开模式(flag)

用位或运算|组合多个模式

打开模式 含义
O_CREAT 必要时创建文件
O_TRUNC 删除全部现有数据
O_APPEND 追加到已有数据后面
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读写打开

习题答案

Q01

套接字在网络编程中的作用是什么?为什么称它为套接字?

P2,网络编程就是编写程序让两台联网的计算机相互交换数据。在我们不需要考虑物理连接的情况下,我们只需要考虑如何编写传输软件。操作系统提供了名为 “套接字”,套接字是网络传输用的软件设备
socket 英文原意是插座:我们把插头插到插座上就能从电网获得电力供给,同样,为了与远程计算机进行数据传输,需要连接到 Internet, 而变成中的 “套接字” 就是用来连接该网络的工具

Q02

在服务器端创建套接字后,会依次调用 listen 函数和 accept 函数。请比较并说明两者作用

listen: 调用 listen 函数将套接字转换成可受连接状态(监听)
accept: 调用 accept 函数受理连接请求,并且在没有连接请求的情况调用该函数,不会返回。直到有连接请求为止。二者存在逻辑上的先后关系

Q03

Linux 中,对套接字数据进行 I/O 时可以直接使用 I/O 相关函数;而在 Windows 中则不可以。原因为何?

Linux 把套接字也看作是文件,所以可以用文件 I/O 相关函数;而 Windows 要区分套接字和文件,所以设置了特殊的函数

Q04

创建套接字后一般会给它分配地址,为什么?为了完成地址分配需要调用哪些函数?

套接字被创建之后,只有为其分配了IP地址和端口号后,客户端才能够通过IP地址及端口号与服务器端建立连接,需要调用 bind 函数来完成地址分配。分配地址是通过bind()函数实现

Q05

Linux 中的文件描述符与 Windows 的句柄实际上非常类似。请以套接字为对象说明他们的含义。

Linux 的文件描述符是为了区分指定文件而赋予文件的整数值(相当于编号)。Windows 的文件描述符其实也是套接字的整数值,其目的也是区分指定套接字。

Q06

底层文件 I/O 函数与 ANSI 标准定义的文件 I/O 函数之间有何区别?

在ANSI标准中定义的I/O函数是作为C的标准提供的函数,无论操作系统如何,随时都可以调用。另一方面,低级文件I/O函数是操作系统提供的I/O函数。

Q07

参考本书给出的示例 low_open.c 和 low_read.c, 分别利用底层文件 I/O 和 ANSI 标准 I/O 编写文件复制程序。可任意指定复制程序的使用方法。

   /*****************************low_cpy.c(底层文件I/O)*********************************/
   #include <stdio.h>
   #include <fcntl.h>
   #include <unistd.h>
   #define BUF_SIZE 100
   
   int main(
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值