第一章:理解网络编程和套接字
1. 套接字在网络编程中的作用是什么?为何称它为套接字
套接字是一种传输和接收数据的媒介,使程序员从物理连接的主机之间传输和接收数据所需的协议中解放出来。毕竟,套接字被用作连接互联网庞大网络的工具,因此可以概括为套接字。
2. 在服务器端创建套接字后,会依次调用listen函数和accept函数。请比较并说明二者作用。
listen:将套接字转为可接受连接方式。
accept:受理连接请求,并且在没有连接请求的情况调用该函数,不会返回。直到有连接请求为止。二者存在逻辑上的先后关系。
处于listen阶段的服务器已经做好了交换网络网络数据所需的准备工作,但并没有开放连接给客户端连(类似于餐厅装修好了,但未开业)。accept阶段循环监听,直到用客户端的连接到来。
3. Linux中,对套接字数据进行I/O时可以直接使用文件I/O相关函数;而在Windows中则不可以。原因为何?
Linux 认为套接字就是文件,也就是设计成两者不分的形式,所以套接字输入输出可以使用文件输入输出功能,但是Windows不像 Linux,不把套接字和文件看成是一样的,所以文件输入输出功能和套接字输入输出功能是分开的。
4. 创建套接字后一般会给它分配地址,为什么?为了完成地址分配需要调用哪个函数?
需要地址信息来区分Internet上的套接字。 有了地址,客户端才有连接的目标。bind函数。
5. Linux中的文件描述符与Windows的句柄实际上非常类似。请以套接字为对象说明它们的含义。
Linux 文件描述符是为区分和引用文件而赋予文件的整数值。 inux内部将套接字当做普通文件,Windows中的套接字是套接字句柄。 都是为了区分指定文件而赋予的整数值。
6. 底层文件I/O函数与ANSI标准定义的文件I/O函数之间有何区别?
ANSI标准定义的输入输出函数是由C的标准提供的,与操作系统无关,因此,它可以随时调用,另一方面,低级文件输入输出函数是由操作系统提供的输入输出函数,因此,它是由操作系统定义的输入输出函数。
PS:POSIX:可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX)
# 底层文件I/O和ANSI标准I/O的区别
# POSIX.1 and ISO C标准头文件
7. 参考示例low_open.c和low_read.c,分别利用底层文件I/O和ANSI标准I/O编写文件复制程序。 low_copy.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define BUF_SIZE 100
int main(int argc, char *argv[]){
int src, dst;
int read_cnt;
char buf[BUF_SIZE];
src = open("src.dat",O_RDONLY);
dst = open("dst.dat", O_CREAT|O_WRONLY|O_TRUNC);
if(src==-1){
puts("src.dat open error");
return -1;
}
if(dst==-1){
puts("dst.dat open error");
return -1;
}
while((read_cnt=read(src, buf, BUF_SIZE))!=0){
write(dst, buf, read_cnt);
}
close(src);
close(dst);
return 0;
}
ansi_copy.c
#include <stdio.h>
#define BUF_SIZE 30
int main(){
char buf[BUF_SIZE];
int read_cnt;
FILE* src = fopen("src.dat", "rb");
FILE* dst = fopen("dst.dat", "wb");
if(src==NULL||dst==NULL){
puts("file open error");
return -1;
}
while(1){
read_cnt = fread((void*)buf, 1, BUF_SIZE, src);
if(read_cnt<BUF_SIZE){
if(feof(src)!=0){
fwrite((void*)buf, 1, BUF_SIZE, dst);
break;
}else{
puts("file copy error");
}
break;
}
fwrite((void*)buf, 1, BUF_SIZE, dst);
}
fclose(src);
fclose(dst);
return 0;
}