计算机网络——15套接字编程

套接字编程

Socket编程

Socket编程:应用进程使用传输层提供的服务才能够交换报文,实现应用协议,实现应用
TCP/IP:应用进程使用Socket API访问传输服务
地点:界面上的SAP
方式:Socket API

目标:学习如何构建能借助sockets进行通信的C/S应用程序
socke:分布式应用进程之间的门,传输层协议提供的端到端服务接口

在这里插入图片描述

2种传输层服务的socket类型

  • TCP:可靠的、字节流的服务
  • UDP:不可靠(数据UDP数据报)服务

TCP套接字编程

套接字:应用进程与端到端传输协议(TCP或UDP)之间的门户
TCP服务:从一个进程向另一个进程可靠的传输字节流

服务器首先运行,等待连接建立
服务器进程必须先处于运行状态

  • 创建欢迎socket
  • 和本地端口捆绑
  • 在欢迎socket上阻塞式等待接受用户的连接

客户端主动和服务器建立连接
创建客户端本地套接字(隐式捆绑到本地port)

  • 指定服务器进程的IP地址和端口号,与服务器进程连接

当与客户端连接请求到来时

  • 服务器接受来自客户端的请求,接触阻塞式等待,返回一个新的socket(与欢迎socket不一样),与客户端通信
    • 允许服务器与多个客户端通信
    • 使用的IP和源端口来区分不同的客户端

连接API调用有效时,客户端P与服务器之间建立了TCP连接

从应用程序的角度
TCP在客户端和服务器进程之间提供了可靠的、字节流(管道)服务

C/S模式的应用样例

  • 客户端从标准输入装置读取一行字符,发送给服务器
  • 服务器从socket读取字符
  • 服务器将字符串装换成大写,然后返回给客户端
  • 客户端从socket种读取一行字符,然后打印出来

实际上,这里描述了C-S之间交互的动作次序

数据结构sockaddr_in

IP地址和port捆绑关系的数据结构(标示进程的端节点)

struct socketaddr_in{
    short sin_family;   //AF_INET
    u_short sin_port;   //port
    struct in_addr sin_addr;    //IP address unsigned long
    char sin_zero[8];   //align
};
属性说明
sin_family地址簇,这个结构体不仅仅用于IP的通信,还可以用于其他的通信,这里设置为常量AF_INET,表明是TCP/IP的协议簇
sin_port端口号
sin_addrip地址
sin_zero起对其作用,因为ipx的地址长度比ip的长度,其他地址也是

数据结构hostent

域名和IP地址的数据结构

struct hostent { 
    char *h_name;	//域名
    char **h_aliases;	//别名
    int h_addrtype;	
    int h_length; //地址长度
    char **h_addr_list;	//IP地址
    #define h_addr h_addr_list[0];
}; 
属性类型说明
h_name字符串主机域名
h_aliases字符串数组主机的一系列别名
h_addrtype
h_length数字地址长度
h_addr_list字符串数组ip地址,可以将其复制到sockaddr_in的ip中

作为调用域名解析函数时的参数 返回后,将IP地址拷贝到 sockaddr_in的IP地址部分

C/S socket交互:TCP

在这里插入图片描述

例子:C客户端(TCP)

// client.c
void main(int argc, char *argv[]) {
    // sad表示 server addr
    struct sockaddr_in sad; /* structure to hold an IP address of server */
    int clientSocket; /* socket descriptor */
    struct hostent *ptrh; /* pointer to a host table entry */
    char Sentence[128];
    char modifiedSentence[128];
    //	argv[0]是程序的名字
    host = argv[1]; // argv[1] 表示服务器的域名
    port = atoi(argv[2]); // argv[2]表示服务端的端口
    clientSocket = socket(PF_INET, SOCK_STREAM, 0);
    // 这里底层自动使用了bind

    // sad先清0
    memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
    sad.sin_family = AF_INET; /* set family to Internet */
    // port先转换成短整形,然后设置成网络次序
    sad.sin_port = htons((u_short)port);
    ptrh = gethostbyname(host);
    /* Convert host name to IP address */
    //将IP地址拷贝到sad.sin_addr
    memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
    connect(clientSocket, (struct sockaddr *)&sad, sizeof(sad));

    gets(Sentence); // get input stream from client
    n=write(clientSocket, Sentence, strlen(Sentence)+1); // send line to server
    n=read(clientSocket, modifiedSentence, sizeof(modifiedSentence)); // read line from server
    printf("FROM SERVER: %s\n",modifiedSentence);
    close(clientSocket);  // close the connection
}

例子:C服务器(TCP)

// server.c
void main(int argc, char *argv[]) {
    // 只有一个参数,就是服务端的端口号
    struct sockaddr_in sad; /* structure to hold an IP address of server*/
    struct sockaddr_in cad; /*client */
    int welcomeSocket, connectionSocket; /* socket descriptor */
    struct hostent *ptrh; /* pointer to a host table entry */
    char clientSentence[128];
    char capitalizedSentence[128];
    // port
    port = atoi(argv[1]);
    welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
    memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
    sad.sin_family = AF_INET; /* set family to Internet */
    sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
    sad.sin_port = htons((u_short)port);/* set the port number */
    // 此处赋值,在表中进行赋值
    bind(welcomeSocket, (struct sockaddr *)&sad, sizeof(sad));
    
    // specify the maximum number of clients that can be queued
    listen(welcomeSocket, 10)
        while(1) {
            connectionSocket=accept(welcomeSocket, (struct sockaddr *)&cad, &alen);
            n=read(connectionSocket, clientSentence, sizeof(clientSentence));
            // capitalize Sentence and store the result in capitalizedSentence
            n=write(connectionSocket, capitalizedSentence, strlen(capitalizedSentence)+1);
            close(connectionSocket);
        }
}

UDP Socket编程

UDP在客户端和服务器之间没有连接

  • 没有握手
  • 发送端在每一个报文中明确地指明目标的IP地址和端口号
  • 服务器必须从收到的分组中提取出发送端的IP地址和端口号

传送的数据可能乱序,也可能丢失

进程视角看UDP服务
UDP为客户端和服务器提供不可靠的字节组的传送服务

C/S交互:UDP

在这里插入图片描述

例子:C客户端

/* client.c */
void main(int argc, char *argv[])
{
    struct sockaddr_in sad; /* structure to hold an IP address */
    int clientSocket; /* socket descriptor */
    struct hostent *ptrh; /* pointer to a host table entry */
    char Sentence[128];
    char modifiedSentence[128];
    host = argv[1]; port = atoi(argv[2]);
    clientSocket = socket(PF_INET, SOCK_DGRAM, 0);
    /* determine the server's address */
    memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
    sad.sin_family = AF_INET; /* set family to Internet */
    sad.sin_port = htons((u_short)port);
    ptrh = gethostbyname(host);
    /* Convert host name to IP address */
    memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
    gets(Sentence);
    addr_len =sizeof(struct sockaddr);
    n=sendto(clientSocket, Sentence, strlen(Sentence)+1, (struct sockaddr *) &sad, addr_len);
    n=recvfrom(clientSocket, modifiedSentence, sizeof(modifiedSentence),(struct sockaddr *) &sad, &addr_len);
    printf("FROM SERVER: %s\n",modifiedSentence);
    close(clientSocket);
}

例子:C服务器

/* server.c */
void main(int argc, char *argv[])
{
    struct sockaddr_in sad; /* structure to hold an IP address */
    struct sockaddr_in cad;
    int serverSocket; /* socket descriptor */
    struct hostent *ptrh; /* pointer to a host table entry */
    char clientSentence[128];
    char capitalizedSentence[128];
    port = atoi(argv[1]);
    serverSocket = socket(PF_INET, SOCK_DGRAM, 0);
    memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
    sad.sin_family = AF_INET; /* set family to Internet */
    sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
    sad.sin_port = htons((u_short)port);/* set the port number */
    bind(serverSocket, (struct sockaddr *)&sad, sizeof(sad));
    while(1) {
        n=recvfrom(serverSocket, clientSentence, sizeof(clientSentence), 0
                   (struct sockaddr *) &cad, &addr_len );
        /* capitalize Sentence and store the result in capitalizedSentence*/
        n=sendto(serverSocket , capitalizedSentence, strlen(capitalizedSentence)+1,
                 (struct sockaddr *) &cad, &addr_len);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/392159.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发系列教程(二十四)--List 列表操作(3)

列表编辑 1、新增列表项 定义列表项数据结构和初始化列表数据,构建列表整体布局和列表项。 提供新增列表项入口,即给新增按钮添加点击事件。 响应用户确定新增事件,更新列表数据。 2、删除列表项 列表的删除功能一般进入编辑模式后才可…

stable diffusion webui学习总结(2):技巧汇总

一、脸部修复:解决在低分辨率下,脸部生成异常的问题 勾选ADetailer,会在生成图片后,用更高的分辨率,对于脸部重新生成一遍 二、高清放大:低分辨率照片提升到高分辨率,并丰富内容细节 1、先通过…

Leetcode-429.N叉树的层序遍历

题目: 给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。 树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。 示例 1: 输入&#xff…

Rocky Linux 下载安装

一、VMware Workstation下载安装 1、安装教程 VMware Workstation下载安装(含密钥) 二、VMware Workstation 创建虚拟机 1、创建教程 VMware Workstation 创建虚拟机 三、Rocky Linux 下载 1、下载官网 RockyLinux.org 2、选择X86架构_64位系统_DVD镜…

【C++初阶】第三站:类和对象(中) -- 日期计算器

目录 前言 日期类的声明.h 日期类的实现.cpp 获取某年某月的天数 全缺省的构造函数 拷贝构造函数 打印函数 日期 天数 日期 天数 日期 - 天数 日期 - 天数 前置 后置 前置 -- 后置-- 日期类中比较运算符的重载 <运算符重载 运算符重载 ! 运算符重载 …

JavaScript设计模式与开发实战

JavaScript设计模式与开发实践 第一章、面向对象的JavaScript 1.1 多态 类似java面向对象&#xff0c;通过继承共有特征&#xff0c;来实现不同方法。JavaScript的多态就是把“做什么”和“谁去做”分离&#xff0c;消除类型间的耦合关系。 他的作用就是把过程化的条件分支…

TIM编码器接口(编码器测速)

定时器编码器接口自动计次--------->对应手册14.3.12编码器接口模式 应用场景&#xff1a; 电机控制PWM驱动电机&#xff0c;编码器测电机速度&#xff0c;PID算法闭环控制 ------------------------------------------------------------------------------------------…

【Linux】程序地址空间 -- 详解 Linux 2.6 内核进程调度队列 -- 了解

一、程序地址空间回顾 在学习 C/C 时&#xff0c;我们知道内存会被分为几个区域&#xff1a;栈区、堆区、全局/静态区、代码区、字符常量区等。但这仅仅是在语言层面上的理解&#xff0c;是远远不够的。 如下空间布局图&#xff0c;请问这是物理内存吗&#xff1f; 不是&…

LV.23 D3 STM32 GPIO口操作平台介绍 学习笔记

一、GPIO的基本概念及寄存器介绍 1.1 GPIO接口简介 通用输入输出接口GPIO是嵌入式系统、单片机开发过程中最常用的接口&#xff0c;用户可以通过编程灵活的对接口进行控制&#xff0c;实现对电路板上LED、数码管、按键等常用设备控制驱动&#xff0c;也可以作为串口的数据收发…

文件上传漏洞--Upload-labs--Pass02--Content-Type绕过

一、什么是 Content-Type 我们在上传文件时利用 Burpsuite 进行抓包&#xff0c;如下图所示&#xff1a; 上传文件后台的源代码可能会对 Content-Type 进行规定&#xff0c;设置白名单 或 黑名单&#xff0c;这时就要利用Content-Type绕过上传含有恶意代码的 php文件。 二、代…

2023年中国数据智能管理峰会(DAMS上海站2023):核心内容与学习收获(附大会核心PPT下载)

随着数字经济的飞速发展&#xff0c;数据已经渗透到现代社会的每一个角落&#xff0c;成为驱动企业创新、提升治理能力、促进经济发展的关键要素。在这样的背景下&#xff0c;2023年中国数据智能管理峰会&#xff08;DAMS上海站2023&#xff09;应运而生&#xff0c;汇聚了众多…

解锁Spring Boot中的设计模式—03.委派模式:探索【委派模式】的奥秘与应用实践!

委派模式 文章目录 委派模式1.简述**应用场景****优缺点****业务场景示例** 2.类图3.具体实现3.1.自定义注解3.2.定义抽象委派接口3.3.定义具体执行者3.4.定义委派者(统一管理委派任务)3.5.定义委派者管理类 4.测试4.1.controller层4.2.测试不同场景4.2.1.测试生产部门计算费用…

排序前言冒泡排序

目录 排序应用 常见的排序算法 BubbleSort冒泡排序 整体思路 图解分析 ​ 代码实现 每趟 写法1 写法2 代码NO1 代码NO2优化 时间复杂度 排序概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递…

python in Vscode

背景 对于后端的语言选择&#xff1a; python&#xff0c;java&#xff0c;JavaScript备选。 选择Python 原因&#xff1a;可能是非IT专业的人中&#xff0c;会Python的人比较多。 目的 之前使用的IDE是VSCODE&#xff0c;在WSL的环境下使用。现在需要在在WSL的VSCODE下使…

【开源】SpringBoot框架开发创意工坊双创管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 管理员端2.2 Web 端2.3 移动端 三、系统展示四、核心代码4.1 查询项目4.2 移动端新增团队4.3 查询讲座4.4 讲座收藏4.5 小程序登录 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的创意工坊双创管理…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之NavRouter组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之NavRouter组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、NavRouter组件 导航组件&#xff0c;默认提供点击响应处理&#xff0c;不需要…

MySQL数据库⑪_C/C++连接MySQL_发送请求

目录 1. 下载库文件 2. 使用库 3. 链接MySQL函数 4. C/C链接示例 5. 发送SQL请求 6. 获取查询结果 本篇完。 1. 下载库文件 要使用C/C连接MySQL&#xff0c;需要使用MySQL官网提供的库。 进入MySQL官网选择适合自己平台的mysql connect库&#xff0c;然后点击下载就行…

相机图像质量研究(27)常见问题总结:补光灯以及遮光罩对成像的影响--遮光罩

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

视频生成模型作为世界模拟器

我们探索了在视频数据上大规模训练生成模型。具体来说&#xff0c;我们联合训练文本条件扩散模型&#xff0c;处理不同持续时间、分辨率和宽高比的视频和图像。我们利用一种在时空补丁上操作视频和图像潜码的transformer架构。我们最大的模型&#xff0c;Sora&#xff0c;能够生…

【初始RabbitMQ】了解和安装RabbitMQ

RabbitMQ的概念 RabbitMQ是一个消息中间件&#xff1a;他可以接受并转发消息。例如你可以把它当做一个快递站点&#xff0c;当你要发送一个包 裹时&#xff0c;你把你的包裹放到快递站&#xff0c;快递员最终会把你的快递送到收件人那里&#xff0c;按照这种逻辑 RabbitMQ 是 …