《TCP IP网络编程》第一章

这篇具有很好参考价值的文章主要介绍了《TCP IP网络编程》第一章。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        2023.6.28 正式开始学习网络编程。 每一章每一节的笔记都会记录在博客中以便复习。

第1章

1.1理解网络编程和套接字

        网络编程又叫套接字编程。所谓网络编程,就是编写程序使两台连网的计算机相互交换数据。 为什么叫套接字编程? 我们平常将插头插入插座上就能从电网中获取电力,同样的道理,为了与远程计算机进行数据传输,需要连接到因特网,而编程中的“套接字”就是用来链接网络的工具。

        服务器端创建的套接字又叫服务器端套接字或者监听套接字。 其请求连接的套接字创建过程分为四步:

  1. 调用socket函数创建套接字
  2. 调用bind函数分配IP地址和端口号
  3. 调用listen函数转为可接受请求状态
  4. 调用accept函数受理连接请求

        请求连接的客户端套接字创建过程如下两步:

  1. 调用socket函数创建套接字
  2. 调用connect函数向服务器端发送连接请求

        值得注意的是:创建完套接字,并不会马上区分为服务器端或客户端。 如果接下来紧接着调用bind、listen等函数则成为服务器端套接字;如果调用connect函数则称为客户端套接字。

        接下来在linux环境中编译并执行上述两个实例:hello_server.c文件和hello_client.c文件。

        分别对客户端和服务端程序进行编译:    

gcc hello_server.c -o hserver
gcc hello_client.c -o hclient

        该命令中的-o是用来指定可执行文件名的可选参数,因此,编译后将生成可执行文件hserver和hclient。

            运行:

./hserver 9190
./hclient 127.0.0.1 9190

        运行的时候,首先在 9190 端口启动服务,然后 heserver 就会一直等待客户端进行响应,当客户端监听位于本地的 IP 为 127.0.0.1 的地址的9190端口时,客户端就会收到服务端的回应,输出`Hello World!`。

《TCP IP网络编程》第一章,书籍专栏,网络,tcp/ip,网络协议,网络编程

        ps:执行过程中输入的127.0.0.1是本地计算机的IP地址。 如果在同一台计算机中同时运行服务器端和客户端,将采用这种连接方式。 但如果服务器端和客户端在不同计算机中运行,则应采用服务器端所在计算机的IP地址。


1.2基于Linux的文件操作

                                                  底层访问和文件描述符

        在linux中,socket也是文件的一种,因此在网络数据传输过程中可以使用文件I/O相关的函数。而Windows需要区分socket和文件,因此在Windows中需要调用特殊的数据传输相关函数。

        每当生成文件或套接字,操作系统将返回分配给他们的整数,(即文件描述符),这个整数将成为程序员与操作系统之间良好沟通的渠道,实际上,文件描述符是为了方便称呼系统创建的文件或套接字而赋予的数。 文件描述符也成为文件句柄,“句柄”是Windows中的术语,Linux平台则使用“描述符”。

                                                        打开文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *path, int flag);
/*
成功时返回文件描述符,失败时返回-1
path : 文件名的字符串地址
flag : 文件打开模式信息
*/

                                                         关闭文件

#include <unistd.h>
int close(int fd);
/*
成功时返回 0 ,失败时返回 -1
fd : 需要关闭的文件或套接字的文件描述符
*/

        若调用此函数同时传递文件描述符参数,则关闭(终止)响应文件。另外需要注意的是,此函数不仅可以关闭文件,还可以关闭套接字。再次证明了「Linux 操作系统不区分文件与套接字」的特点。 

                                                    将数据写入文件

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbytes);
/*
成功时返回写入的字节数 ,失败时返回 -1
fd : 显示数据传输对象的文件描述符
buf : 保存要传输数据的缓冲值地址
nbytes : 要传输数据的字节数
*/

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

创建新文件并保存数据:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
void error_handling(char *message);

int main()
{
    int fd;
    char buf[] = "Let's go!\n";
    // O_CREAT | O_WRONLY | O_TRUNC 是文件打开模式,将创建新文件,并且只能写。如存在 data.txt 文件,则清空文件中的全部数据。
    fd = open("data.txt", O_CREAT | O_WRONLY | O_TRUNC);
    if (fd == -1)
        error_handling("open() error!");
    printf("file descriptor: %d \n", fd);
    // 向对应 fd 中保存的文件描述符的文件传输 buf 中保存的数据。
    if (write(fd, buf, sizeof(buf)) == -1)
        error_handling("write() error!");
    close(fd);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

         运行后会生成一个data.txt的文件,里面有Let's go!

                                                        读取文件中的数据

        与之前的write()函数相对应,read()函数用来输入(接收)数据:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t nbytes);
/*
成功时返回接收的字节数(但遇到文件结尾则返回 0),失败时返回 -1
fd : 显示数据接收对象的文件描述符
buf : 要保存接收的数据的缓冲地址值。
nbytes : 要接收数据的最大字节数
*/

        下面代码通过 read() 函数读取 data.txt 中保存的数据:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define BUF_SIZE 100
void error_handling(char *message);

int main()
{
    int fd;
    char buf[BUF_SIZE];

    fd = open("data.txt", O_RDONLY);
    if (fd == -1)
        error_handling("open() error!");
    printf("file descriptor: %d \n", fd);

    if (read(fd, buf, sizeof(buf)) == -1)
        error_handling("read() error!");
    printf("file data: %s", buf);
    close(fd);
    return 0;
}
void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

实验结果: 

《TCP IP网络编程》第一章,书籍专栏,网络,tcp/ip,网络协议,网络编程

         low.open.c创建文件并保存文件数据,运行之后返回文件描述符3。用cat命令输出data.txt的文件内容,可以确认确实向文件传输了数据。

        low.read.c程序则通过read函数读取了data.txt中保存的数据。运行之后打印文件描述符以及文件的内容。 

        fd_seri.c 程序同时创建文件和套接字:

    fd1 = socket(PF_INET, SOCK_STREAM, 0);
    fd2 = open("test.dat", O_CREAT | O_WRONLY | O_TRUNC);
    fd3 = socket(PF_INET, SOCK_DGRAM, 0);

然后分别打印其文件描述符得到3、4、5,描述符从3开始以由小到大的顺序编号,因为0、1、2是分配给标注能I/O的描述符。如下图:

​​​​​​​

1.5 习题

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

        套接字是一种用于在网络上进行通信的编程接口。套接字允许不同计算机上的进程通过网络进行数据传输。它提供了一种机制,使得计算机之间可以建立连接、发送和接收数据。套接字使得应用程序能够利用网络进行通信,实现客户端和服务器之间的数据交换。

        它被称为套接字,是因为它类比于电话通信中的插座,作为网络通信的端点连接点。

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

        listen函数用于将套接字设置为被动监听模式,以接受客户端的连接请求。

        accept函数用于接受客户端的连接请求,并创建一个新的套接字来处理与该客户端的通信。

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

        这是因为在Unix-like系统中,包括Linux,一切皆文件的思想被广泛采用,将各种资源(包括套接字)都抽象为文件描述符的形式,统一了数据的读写接口。

        然而,在Windows操作系统中,套接字不被视为文件描述符,因此不能直接使用文件I/O相关函数进行数据的读写操作。

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

        在网络编程中,创建套接字后需要给它分配地址,主要是为了使其他计算机能够找到并与该套接字建立连接。通过分配地址,可以指定套接字的IP地址和端口号,从而唯一标识该套接字在网络中的位置。

        为了完成地址分配,需要调用bind函数。bind函数用于将套接字与特定的IP地址和端口号进行绑定。文章来源地址https://www.toymoban.com/news/detail-516367.html

到了这里,关于《TCP IP网络编程》第一章的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • TCP/IP网络编程(一)

    1.1.1 构建打电话套接字 以电话机打电话的方式来理解套接字。 **调用 socket 函数(安装电话机)时进行的对话:**有了电话机才能安装电话,于是就要准备一个电话机,下面函数相当于电话机的套接字。 **调用 bind 函数(分配电话号码)时进行的对话:**套接字同样如此。就想

    2024年02月03日
    浏览(36)
  • TCP/IP网络编程(一) 理解网络编程和套接字

    网络编程和套接字概要 网络编程就是编写程序使两台联网的计算机相互交换数据 为了与远程计算机进行数据传输,需要连接因特网,而编程种的套接字就是用来连接该网络的工具。 构建套接字 1.调用soecket函数创建套接字 2.调用bind函数给套接字分配地址 3.调用listen函数将套

    2024年02月11日
    浏览(44)
  • 《TCP IP网络编程》第六章

    UDP 套接字的特点:         通过寄信来说明 UDP 的工作原理,这是讲解 UDP 时使用的传统示例,它与 UDP 的特点完全相同。寄信前应先在信封上填好寄信人和收信人的地址,之后贴上邮票放进邮筒即可。当 然,信件的特点使我们无法确认信件是否被收到。邮寄过程中也可能

    2024年02月16日
    浏览(39)
  • 《TCP IP网络编程》第十章

    并发服务端的实现方法:         通过改进服务端,使其同时向所有发起请求的客户端提供服务,以提高平均满意度。而且,网络程序中数据通信时间比 CPU 运算时间占比更大,因此,向多个客户端提供服务是一种有效的利用 CPU 的方式。接下来讨论同时向多个客户端提供

    2024年02月15日
    浏览(31)
  • 《TCP/IP网络编程》阅读笔记--域名及网络地址

    目录 1--域名系统 2--域名与 IP 地址的转换 2-1--利用域名来获取 IP 地址 2-2--利用 IP 地址获取域名 3--代码实例 3-1--gethostbyname() 3-2--gethostbyaddr()         域名系统(Domain Name System, DNS )是对 IP 地址和域名进行相互转换 的系统,其核心是 DNS 服务器;         一般来说, IP

    2024年02月09日
    浏览(51)
  • 【网络编程】网络通信基础——简述TCP/IP协议

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程的一点学习心得,欢迎大家在评论区交流讨论💌 ip地址简单来说就是用来描述网络上一个设备的所在位置。 端

    2024年02月04日
    浏览(42)
  • 《TCP IP网络编程》第四章

            根据数据传输方式的不同,基于网络协议的套接字一般分为 TCP 套接字和 UDP 套接字。因为 TCP 套接字是面向连接的,因此又被称为基于流(stream)的套接字。                 TCP 是 Transmission Control Protocol (传输控制协议)的简写,意为「对数据传输过程的

    2024年02月15日
    浏览(31)
  • 《TCP IP网络编程》第十八章

    线程背景:         第 10 章介绍了多进程服务端的实现方法。多进程模型与 select 和 epoll 相比的确有自身的优点,但同时也有问题。如前所述, 创建(复制)进程的工作本身会给操作系统带来相当沉重的负担。而且,每个进程都具有独立的内存空间,所以进程间通信的实

    2024年02月12日
    浏览(39)
  • 《TCP IP网络编程》第十三章

    Linux 中的 send recv:          send 函数定义:         recv 函数的定义:         send 和 recv 函数的最后一个参数是收发数据的可选项,该选项可以用位或(bit OR)运算符(| 运算符)同时传递多个信息。send recv 函数的可选项意义: MSG_OOB:发送紧急消息 :     

    2024年02月15日
    浏览(28)
  • 《TCP IP网络编程》第三章

    3.1 分配给套接字的IP地址与端口号         IP 是 Internet Protocol(网络协议)的简写,是为收发网络数据而分配给计算机的值。端口号并非赋予计算机的值,而是为了区分程序中创建的套接字而分配给套接字的序号。              为使计算机连接到网络并收发数据,必

    2024年02月13日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包