一 理解网络编程和套接字

1.什么是网络编程?

网络编程就是编写程序使两台联网的计算机交换数据。

2.两台计算机之间用什么传输数据?

硬件+软件

硬件:物理的连接

软件:操作系统提供的名为socket的软件设备

socket:可以用来实现两台计算机的网络连接

3.套接字的种类?

TCP套接字和UDP套接字

4.接受连接请求的套接字的创建过程?

以实现能够接听电话为例------->实现服务端的步骤

#include<sys/socket.h>

第一步:调用socket函数创建套接字--------->能够接电话的第一步是准备一个电话

int socket(int domin,int type,int protocol);

第二步:调用bind函数分配IP地址和端口号------>分配电话号码确保能打通电话

int bind(int sockfd,struct sockaddr *myaddr,socklen_t addrlen);

第三步:调用listen函数转为可接收请求状态------->连接电话线并等待来电(电话机转为可接听状态,等待响应打电话的请求)

int listen(int sockfd,int backlog);

第四步:调用accept函数受理连接请求------------>拿起话筒接通电话

int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);

5.用于请求连接的客户端套接字

以能够进行打电话(用于请求连接)为例-------->实现客户端的步骤

第一步:调用socket函数构建套接字

int socket(int domin,int type,int protocol);

第二步:调用connect函数向服务器端发送连接请求

int connect(int sockfd,struct sockaddr *serv_addr,socklen_t addrlen);

先运行服务器端编写的程序,服务器端调用的accept函数等待返回,再运行客户端编写的程序,可以看到消息的传输过程,同时发现,完成消息传输后,服务器端和客户端都停止运行。 再次运行程序前需等待,上面的服务器端无法立即重新运行,必须更改之前输入的端号9190,后面会解释原因。

6.套接字和文件的联系讨论

对于linux而言,socke也被认为是一个文件,因此在网络数据传输过程中自然可以使用文件IO的相关函数。在Window环境下,是要区分socket和文件的,故需要调用特殊的数据传输相关函数。

底层文件访问(Low-Level File Access)和文件描述符(File Descriptor)

底层文件访问:非标准的规定的操作系统独立提供的文件访问。

文件描述符:系统分配给文件或套接字的整数。

文件和套接字一般经过创建过程才会被分配文件描述符。而表中的3种输入输出对象即使未经过特殊的创建过程,程序开始运行后也会被自动分配文件描述符。

文件描述符(windows中称句柄)的理解:每当生成文件或套接字,操作系统将返回分配给他们的整数,这个整数将成为程序员和操作系统直接交流的渠道,文件描述符只不过是为了方便称呼操作系统创建的文件或套接字而赋予的数而已。

7.文件的基本操作

打开文件

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int open(const char *path,int flag);//path:文件名的字符串地址,flag:文件打开模式信息   成功返回文件描述符,失败返回-1

文件的打开模式------->如果需要传递多个参数,则应该通过位或运算符(OR)组合并传递。

文件描述符 对象
0 标准输入:Standard Input
1 标准输出:Standard Output
2 标准错误:Standard Error

关闭文件----->此函数也可以关闭套接字

#include<unistd.h>

int close(int fd);//fd:需要关闭的文件或套接字的文件描述符,成功返回0,失败返回-1;

将数据写入文件

此函数定义中,size_t是通过typedef声明的unsigned int类型,对ssize_t来说,size_t前面多加的s代表signed,即ssize_t是通过typedef声明的signed int类型。

#include<unistd.h>
ssize_t write(int fd,const void* buf,size_t nbytes);//成功返回写入的字节数,失败返回-1
//fd:显示数据传输对象的文件描述符
//buf:保存要传输数据的缓冲地址值
//nbytes:要传输数据的字节数
打开模式 含义
O_CREAT 必要时创建文件
O_TRUNC 删除全部现有数据
O_APPEND 维持现有数据,保存到其后面
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读写打开

读取文件中的数据

#include<unistd.h>
ssize_t read(int fd,void *buf,size_t nbytes);
//fd:显示数据传输对象的文件描述符
//buf:保存要传输数据的缓冲地址值
//nbytes:要传输数据的字节数

文件描述符与套接字

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/socket.h>

int main(void)
{
    int fd1,fd2,fd3;
    fd1=socket(PF_INET,SOCK_STREAM,0);
    fd2=open("test.dat",O_CREAT|O_WRONLY|O_TRUNC);
    fd3=socket(PF_INET,SOCK_DGRAM,0);
    printf("file descriptor 1:%d\n",fd1);
    printf("file descriptor 2:%d\n",fd2);
    printf("file descriptor 3:%d\n",fd3);
    
    close(fd1);
    close(fd2);
    close(fd3);
    return 0;
}
//第9-11行:创建1个文件和2个套接字
//第13-15行:输出之前创建的文件描述符的整数值

Windows平台套接字的实现

第一步:为Windows套接字编程设置头文件和库

第二步:Winsock的初始化

第三步:基于Windows的套接字相关函数及实例

windows中文件句柄和套接字句柄与Linux平台存在的自然差异性。

8 习题(https://github.com/riba2534/TCP-IP-NetworkNote 注:此处搬运的是GitHub大佬们的答案)

❗以下部分的答案,仅代表我个人观点,可能不是正确答案

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

    答:操作系统会提供「套接字」(socket)的部件,套接字是网络数据传输用的软件设备。因此,「网络编程」也叫「套接字编程」。「套接字」就是用来连接网络的工具。

  2. 在服务器端创建套接字以后,会依次调用 listen 函数和 accept 函数。请比较二者作用。

    答:调用 listen 函数将套接字转换成可受连接状态(监听),调用 accept 函数受理连接请求。如果在没有连接请求的情况下调用该函数,则不会返回,直到有连接请求为止。

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

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

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

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

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

答:暂略。

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

    答:文件 I/O 又称为低级磁盘 I/O,遵循 POSIX 相关标准。任何兼容 POSIX 标准的操作系统上都支持文件I/O。标准 I/O 被称为高级磁盘 I/O,遵循 ANSI C 相关标准。只要开发环境中有标准 I/O 库,标准 I/O 就可以使用。(Linux 中使用的是 GLIBC,它是标准C库的超集。不仅包含 ANSI C 中定义的函数,还包括 POSIX 标准中定义的函数。因此,Linux 下既可以使用标准 I/O,也可以使用文件 I/O)。

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

    答:暂略。

posted @ 2023-08-26 14:21  天涯橄榄石  阅读(52)  评论(0)    收藏  举报