TCP/IP 网络编程(四)


套接字和标准 I/O

标准 I/O 函数的优点

  • 具有良好的可移植性
  • 可以利用缓冲提高性能

创建套接字时,操作系统将生成用于 I/O 的缓冲。此缓冲在执行 TCP 协议时发挥重要作用。若使用标准函数,将会获得额外的另一缓冲的支持。

函数缓冲是为了提高传输性能,套接字缓冲是为了实现协议,如窗口控制、重传等。

通过以下两个角度考虑性能的提高:

  • 传输的数据量
  • 数据向输出缓冲移动的次数

标准函数的缺点:

  • 不容易进行双向通信
  • 有时可能频繁使用fflush函数
  • 需要以FILE结构体指针的形式返回文件描述符

使用标准 I/O 函数

指针转换

#include <stdio.h>

FILE * fdopen(int fildes, const char * mode); // 将文件描述符转换为 FILE 结构体指针

~ fildes:  文件描述符
~ mode: 打开模式,读模式(r)和写模式(w)
FILE * fp;
int fd = open("data.dat", O_WRONLY|O_CREAT|O_TRUNC);
fp = fdopen(fd, "w");
...
fclose(fp);

转换为文件描述符

#include <stdio.h>

int fileno(FILE * stream); // 失败返回 -1

基于套接字的标准 I/O 函数使用

echo_stdserv.c
echo_client.c

I/O 分离的好处

  1. 前面讨论过通过调用fork函数复制出一个文件描述符,以区分输入和输出中使用的文件描述符。

    • 通过分开输入过程和输出过程降低编码实现的难度
    • 与输入无关的输出操作可以提高速度
  2. 创建读模式FILE和写模式FILE指针分离输入工具和输出工具。
    • 为了将FILE指针按照读模式和写模式加以区分
    • 降低实现难度
    • 通过区分I/O缓存提高性能

文件描述符的复制和半关闭

对同一个文件描述符执行转换FILE指针之后的模型如下:

两个指针指向同一个文件描述符,因此,针对任意一个FILE指针调用fclose函数都会关闭文件描述符,也就是终止套接字。

上述情况是我们应该避免的,那么该如何实现半关闭呢?

只要构造出下面的模型即可:

利用各自的文件描述符创建指针,因为只有在销毁所有文件描述符后才销毁套接字,这由操作系统保证。

针对写模式指针关闭时,只能销毁对应的文件描述符,而不能销毁套接字。

这还是不完整的,因为可以通过原件文件描述符进行I/O。稍后给出具体实现。

复制文件描述符

此处讨论的复制和fork函数复制整个进程不同,我们要做的是在同一进程中存在同一套接字的不同文件描述符。

#include <unistd.h>

int dup(int fildes);
int dup2(int fildes, int fildes2);

~ fildes: 需要复制的文件描述符
~ fildes2: 明确指定的文件描述符整数值

复制文件描述符后流的分离

FILE * readfp;
FILE * writefp;
...
readfp = fdopen(clnt_sock, "r");
writefp = fdopen(dup(clnt_sock), "w");
...
fflush(writefp);
shutdown(fileno(writefp), SHUT_ER); // 服务器进入半关闭状态,并向客户端发送EOF。调用该函数时,无论复制出多少文件描述符都将进入半关闭状态,同时传递EOF。
时间: 2024-11-05 12:33:09

TCP/IP 网络编程(四)的相关文章

《TCP/IP网络编程》

<TCP/IP网络编程> 基本信息 作者: (韩)尹圣雨 译者: 金国哲 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787115358851 上架时间:2014-6-19 出版日期:2014 年6月 开本:16开 页码:1 版次:1-1 所属分类:计算机 > 计算机网络 > 网络协议 > TCP/IP 更多关于>>><TCP/IP网络编程> 编辑推荐 为初学者准备的网络编程 本书涵盖操作系统.系统编程.TCP/IP协议等多种

浅谈TCP/IP网络编程中socket的行为

我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: . TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) . Socket I/O系统调用(重点如read/write),这是TCP/IP协议在应用层表现出来的行为. . 编写Performant, Scalable的服务器程序.包括多线程.IO Multiplexing.非阻塞.异步等各种技术. 关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illust

TCP/IP网络编程系列之四(初级)

TCP/IP网络编程系列之四-基于TCP的服务端/客户端 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流的套接字.在了解TCP之前,先了解一下TCP所属的TCP/IP协议栈. 如图所示,TCP/IP协议栈共分为4层,可以理解成数据收发分成了4个层次化过程. 链路层 它是物理链接领域标准化结果,也是最基本的领域,专门定义LAN.WAN.MAN等网络标准.若两台计算机通过网络进行数据交换,链路层就负责整个物

TCP/IP网络编程之基于TCP的服务端/客户端(二)

回声客户端问题 上一章TCP/IP网络编程之基于TCP的服务端/客户端(一)中,我们解释了回声客户端所存在的问题,那么单单是客户端的问题,服务端没有任何问题?是的,服务端没有问题,现在先让我们回顾下服务端的I/O代码 echo_server.c --while ((str_len = read(clnt_sock, messag, 1024)) != 0) write(clnt_sock, messag, str_len);-- 接着,我们回顾客户端的代码 echo_client.c -- wr

TCP/IP 网络编程 (抄书笔记 1) -- TCP

TCP/IP 网络编程 (抄书笔记 1) – TCP TCP/IP 网络编程 (抄书笔记 1) – TCP Table of Contents server client 更好的 client 端实现 来源: <TCP/IP 网络编程> 抄书: 通信的双方都各自 拥有 输入缓存和输出缓存 socket 的 write 函数并不是立即传输数据, 而是写到输出缓存区, 到达另一端的输入缓存区 socket 的 read 函数调用的瞬间, 就从输入缓存区中读取数据 TCP 协议中的滑动窗口会保证 数

TCP/IP 网络编程 (抄书笔记 2) -- UDP

TCP/IP 网络编程 (抄书笔记 2) – UDP TCP/IP 网络编程 (抄书笔记 2) – UDP Table of Contents server client connect 来源: <TCP/IP 网络编程> 抄书: TCP 协议若要向 10 个客户端提供服务, 除了需要 listen 套接字外, 还需要 10 个服务器端套接字 (accept), 但是在 UDP 中, 不管是服务器端还是客户端都只需要 1 个套接字 udp 的 client 不需要 bind, 调用 sendt

TCP/IP 网络编程 (抄书笔记 4) -- 管道: 进程间通信

TCP/IP 网络编程 (抄书笔记 4) – 管道: 进程间通信 TCP/IP 网络编程 (抄书笔记 4) – 管道: 进程间通信 int fds[2]; pipe(fds); write(fds[1], buf, strlen(buf)); read(fds[0], buf, BUF_SIZE); 如果两个进程的通信只是 单纯的一方写, 然后另一方读 的情况, 那么 我们的管道操作没有问题, 但是: char str1[] = "str1"; char str2[] = "

TCP/IP 网络编程 (抄书笔记 3) -- 僵尸进程和多任务并发服务器

TCP/IP 网络编程 (抄书笔记 3) – 僵尸进程和多任务并发服务器 TCP/IP 网络编程 (抄书笔记 3) – 僵尸进程和多任务并发服务器 Table of Contents 僵尸进程的产生 避免僵尸进程 信号 多任务的并发服务器 僵尸进程的产生 子进程先退出, 父进程没有退出 ==> 僵尸进程 父进程先退出, 子进程没有退出 ==> 子进程被 0 号进程回收, 不会产生僵尸进程 pid_t pid = fork(); if (pid == 0) { // child printf(&

TCP/IP网络编程系列之三

TCP/IP网络编程系列之三-地址族与数据序列 分配给套接字的IP地址和端口 IP是Internet Protocol (网络协议)的简写,是为首发网络数据而分配给计算机的值.端口号并非赋予计算机值,而是为了区分程序中创建的套接字而分配给套接字的序号. 网络地址 网络地址分为IPV4和IPV6,分别你别为4个字节地址簇和6个字节地址簇.IPV4标准的4个字节的地址分为网络地址和主机地址,且分为A.B.C.D.E 等类型.一般很少用到E类型.如下图所示:net-id指网络ID,host-id指主机

TCP/IP网络编程系列之二

套接字类型与协议设置 我们先了解一下创建套接字的那个函数 int socket(int domain,int type,int protocol);成功时返回文件描述符,失败时返回-1.其中,domain是套接字使用中的协议族(Protocol Family)信息.type套接字类型里面的数据传输类型信息.protocol计算机通信中使用的协议信息. 协议族(Protocol Family) 协议族类型有: PE_INET IPV4 PE_INET6 IPV6 PF_LOCAL 本地通信的UNI