首页 > 其他分享 >第十三章学习笔记

第十三章学习笔记

时间:2023-11-30 14:58:35浏览次数:40  
标签:addr IP 笔记 server 学习 TCP 第十三章 接字 端口号

引言

本章论述了TCP/IP 和网络编程,分为两个部分。第一部分论述了TCP/IP协议及其应用,具体包括 TCP/IP 栈、IP地址、主机名、DNS、IP数据包和路由器;介绍了TCP/IP 网络中的UDP和 TCP 协议、端口号和数据流;阐述了服务器-客户机计算模型和套接字编程接口;通过使用UDP和TCP套接字的示例演示了网络编程。第一个编程项目可实现一对通过互联网执行文件操作的 TCP服务器-客户机,可让用户定义其他通信协议来可靠地传输文件内容。
本章的第二部分介绍了Web和CGI编程,解释了HTTP编程模型、Web 页面和 Web浏览器;展示了如何配置 Linux HTTPD服务器来支持用户 Web 页面、PHP和CGI编程;阐释了客户机和服务器端动态 Web 页面;演示了如何使用PHP和 CGI创建服务器端动态Web 页面。

TCP/IP协议

从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议。实际生活当中有时也确实就是指这两种协议。然而在很多情况下,它只是利用 IP 进行通信时所必须用到的协议群的统称。具体来说,IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议。他们与 TCP 或 IP 的关系紧密,是互联网必不可少的组成部分。TCP/IP 一词泛指这些协议,因此,有时也称 TCP/IP 为网际协议群。
互联网进行通信时,需要相应的网络协议,TCP/IP 原本就是为使用互联网而开发制定的协议族。因此,互联网的协议就是 TCP/IP,TCP/IP 就是互联网的协议。

IP主机和IP地址

IP地址分为两部分,即 NetworkID 字段和HostID字段。根据划分,IP 地址分为A~E 类。例如,一个B类IP地址被划分为一个16位NetworkID,其中前2位是10,然后是一个16位的 HostID字段。发往IP地址的数据包首先被发送到具有相同 networkID的路由器。路由器将通过 HostID 将数据包转发到网络中的特定主机。每个主机都有一个本地主机名localhost,默认 IP地址为 127.0.0.1。本地主机的链路层是一个回送虚拟设备,它将每个数据包路由回同一个localhost。这个特性可以让我们在同一台计算机上运行TCP/IP 应用程序,而不需要实际连接到互联网。

IP协议

IP协议用于在 IP主机之间发送/接收数据包。IP尽最大努力运行。IP 主机只向接收主机发送数据包,但它不能保证数据包会被发送到它们的目的地,也不能保证按顺序发送。这意味着IP 并非可靠的协议。必要时,必须在IP 层的上面实现可靠性。

UDP/TCP

UDP(用户数据报协议)(RFC768 1980;Comer 1988)在IP上运行,用于发送/接收数据报。与IP类似,UDP不能保证可靠性,但是快速高效。它可用于可靠性不重要的情况。

TCP(传输控制协议)

是一种面向连接的协议,用于发送/接收数据流。TCP也可在IP 上运行,但它保证了可靠的数据传输。通常,UDP类似于发送邮件的USPS,而TCP类似于电话连接。

端口编号

应用程序 =(主机 IP,协议,端口号)
其中,协议是TCP或 UDP,端口号是分配给应用程序的唯一无符号短整数。要想使用UDP或 TCP,应用程序(进程)必须先选择或获取一个端口号。前1024个端口号已被预留。其他端口号可供一般使用。应用程序可以选择一个可用端口号,也可以让操作系统内核分配端口号。

套接字编程

(1)套接字地址

struct sockaddr_in {
sa_family_t sin_family; // AF_INET for TCP/IP
// port number
in_port_t sin_port;
struct in_addr sin_addr;// IP address );
// internet address struct in_addr {
// IP address in network byte order
s_addr;
uint32_t
);

(2)套接字API

服务器必须创建一个套接字,并将其与包含服务器IP 地址和端口号的套接字地址绑定。它可以使用一个固定端口号,或者让操作系统内核选择一个端口号(如果 sin port为0)。为了与服务器通信,客户机必须创建一个套接字。对于UPD套接字,可以将套接字绑定到服务器地址。如果套接字没有绑定到任何特定的服务器,那么它必须在后续的 sendto()/recvfrom()调用中提供一个包含服务器IP 和端口号的套接字地址。

实践

int main() {

char listen_addr_str[] = "0.0.0.0";
size_t listen_addr = inet_addr(listen_addr_str);
int port = 8080;
int server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t addr_size;
char buffer[BUFFER_SIZE];//缓冲区大小
int str_length;
server_socket = socket(PF_INET, SOCK_STREAM, 0);//创建套接字
bzero(&server_addr, sizeof(server_addr));//初始化
server_addr.sin_family = INADDR_ANY;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = listen_addr;
if (bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) {
    printf("绑定失败\n");

    exit(1);

}

if (listen(server_socket, 5) == -1) {

    printf("监听失败\n");

    exit(1);

}

printf("创建tcp服务器成功\n");





fd_set reads,copy_reads;

int fd_max,fd_num;

struct timeval timeout;



FD_ZERO(&reads);//初始化清空socket集合

FD_SET(server_socket,&reads);

fd_max=server_socket;





while (1) {

    copy_reads = reads;

    timeout.tv_sec = 5;

    timeout.tv_usec = 5000;



    //无限循环调用select 监视可读事件

    if((fd_num = select(fd_max+1, &copy_reads, 0, 0, &timeout)) == -1) {

        perror("select error");

        break;

    }

    if (fd_num==0){//没有变动的socket

        continue;

    }



    for(int i=0;i<fd_max+1;i++){

        if(FD_ISSET(i,&copy_reads)){

            if (i==server_socket){//server_socket变动,代表有新客户端连接

                addr_size = sizeof(client_addr);

                client_socket = accept(server_socket, (struct sockaddr *) &client_addr, &addr_size);

                printf("%d 连接成功\n", client_socket);

                char msg[] = "恭喜你连接成功";

                write(client_socket, msg, sizeof(msg));

                FD_SET(client_socket,&reads);

                if(fd_max < client_socket){

                    fd_max=client_socket;

                }

            }else{

                memset(buffer, 0, sizeof(buffer));

                str_length = read(i, buffer, BUFFER_SIZE);

                if (str_length == 0)    //读取数据完毕关闭套接字

                {

                    close(i);

                    printf("连接已经关闭: %d \n", i);

                    FD_CLR(i, &reads);//从reads中删除相关信息

                } else {

                    printf("%d 客户端发送数据:%s \n", i, buffer);

                    write(i, buffer, str_length);//将数据发送回客户端

                }

            }

        }

    }



}



return 0;

}

标签:addr,IP,笔记,server,学习,TCP,第十三章,接字,端口号
From: https://www.cnblogs.com/adbl/p/17867334.html

相关文章

  • 第十二章学习笔记
    第十二章块设备I/O和缓冲区管理1.块设备I//O缓冲区文件系统使用一系列I/O缓冲区作为块设备的缓存内存。当进程试图读取(dev,blk)标识的磁盘块时,他首先在缓冲区缓存中搜索分配给磁盘块的缓冲区。如果缓冲区中存在并且包含有效数据,那么它只需要从缓冲区中读取数据,而无需再次从磁盘中......
  • 第十二周学习笔记
    目录MySQL数据库概述MySQL是开源的关系型数据库服务器软件MySQL的特点数据库的基本管理查看数据库结构数据库的创建和删除插入,查询数据记录修改,删除数据记录维护数据库及用户权限gpt问答记录MySQL数据库概述MySQL是开源的关系型数据库服务器软件目前由Oracle公司开发和维护官......
  • yzy第12次学习笔记
    第14章MySQL数据库系统MySQL(MySQL2018)是一个关系数据库系统。在关系数据库中,数据存储在表中。每个表由多个行和列组成。表中的数据相互关联,表也可能与其他表有关联。MySQL是一个开源数据库管理系统,由服务器和客户机组成。在将客户机连接到服务器后,用户可向服务器输入SQL命令......
  • Spring源码学习之Web数据绑定器WebDataBinder
    WebDataBinder1.描述特殊的数据绑定器用于从web请求参数到JavaBean对象的数据绑定。专为web环境,但不依赖于ServletAPI;作为更具体的DataBinder变体的基类,例如ServletRequestDataBinder。2.注意:数据绑定会暴露对象图中不打算被外部客户端访问或修改的部分,从而导致安全问题。因......
  • 学习笔记12
    第十四章MySQL数据库系统PHPMySQL编程数据库连接:使用PHP连接MySQL数据库,主要方法是使用MySQLi扩展或PDO扩展。通过建立数据库连接,可以实现与数据库的通信。数据库操作:掌握创建、删除、修改和查询数据库表的操作。这包括表结构的定义(如字段类型、主键、外键等)、数据的插入......
  • EMG手势识别学习
    学习项目一:基于EMG和IMU融合信号的手势识别模型学习项目一简介:使用深度学习卷积神经网络实现手势识别......
  • 【必读】开发者必备!轻松学习MySQL事务的使用方法
    在日常开发中我们经常会遇到需要同时处理多个操作的情况,比如在购物时,我们需要同时完成支付和更新库存两个操作。这时,如果其中一个操作失败了,我们就需要进行回滚,以保证数据的一致性。那么,如何在MySQL中实现这样的功能呢?答案就是——事务。下面我们就来介绍一下MySQL事务是什么?它......
  • 【谢华】超脑力高效学习法
    目录记忆法标签表1.字母锁链法2.锁链衍生法3.谐音联想法4.直观记忆法5.位置法扩增单词计划注意事项记忆法【谢华】超脑力高效学习法标签表1.字母锁链法利用字母标签加上锁链法串成一张图片来记忆。例如:熊bear想像一个熊,熊的大腿上叮着一只大蜜蜂(e),蜜蜂被老鹰(e)咬着,老鹰的爪子抓......
  • Nginx loki监控日志的学习
    Nginxloki监控日志的学习背景学习https://mp.weixin.qq.com/s/Qt1r7vzWvCcJpNDilWHuxQ增加了一些自己的理解第一部分nginx日志的完善在logformat的后面增加一个:log_formatjson_analyticsescape=json'{''"msec":"$msec",'#request......
  • Windows平台的prometheus和Grafana的学习与使用
    Windows平台的prometheus和Grafana的学习与使用背景最近没有了linux机器突然想捯饬一下Windows平台的监控与使用所以总结一一下.第一步下载https://prometheus.io/download/https://grafana.com/grafana/download注意需要下载windows平台的安装介质建议是选择zip包.zip包......