计算机网络——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_INETu_short sin_port;   //portstruct in_addr sin_addr;    //IP address unsigned longchar 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 addrstruct 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先清0memset((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_addrmemcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);connect(clientSocket, (struct sockaddr *)&sad, sizeof(sad));gets(Sentence); // get input stream from clientn=write(clientSocket, Sentence, strlen(Sentence)+1); // send line to servern=read(clientSocket, modifiedSentence, sizeof(modifiedSentence)); // read line from serverprintf("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];// portport = 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 queuedlisten(welcomeSocket, 10)while(1) {connectionSocket=accept(welcomeSocket, (struct sockaddr *)&cad, &alen);n=read(connectionSocket, clientSentence, sizeof(clientSentence));// capitalize Sentence and store the result in capitalizedSentencen=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);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

强化学习入门(Matlab2021b)-创建环境【2】

目录 1 前言2 利用step和reset函数创建自定义环境2.1 对象描述2.2 reset函数2.3 step函数2.3 构建自定义环境3 使用匿名函数传递额外的参数4 可视化检查自定义函数的输出参考链接1 前言 本文介绍如何基于MATLAB编写step、reset函数,创建自己的强化学习环境(Environment)。 使…

Windows 中文版下 MSVC 对 UTF-8 支持(避免乱码)

原文:https://blog.iyatt.com/?p14017 1 测试环境 我这里在 Windows 11 专业版 23H2 中文版PowerShell 7.4.1 中,默认的字符编码是 936 GB2312 官方的标识码解释:https://learn.microsoft.com/zh-cn/windows/win32/Intl/code-page-iden…

IDEA的版本控制Local Changes和settings按钮显示问题

经常用idea的小伙伴应该对标题的这两个功能不陌生,特别是Local Changes 周日刚开工,我的idea就过期了,索性就下载了一个2023.3.3版本的,安装好打开一看,发现Local Changes 和 settings的按钮消失了,虽然说…

红外光谱法(IR)应用领域宽广 全球市场增长速度加快

红外光谱法(IR)应用领域宽广 全球市场增长速度加快 红外光谱法(IR),也称为红外分光光度法,分子吸收红外线,引起分子振动能级、转动能级跃迁,获得物质红外吸收光谱,测定物…

专业定制线缆厂家推荐:精工电联-小批量、多品类集成线缆定制的领航者

高品质定制线缆厂家推荐:精工电联-小批量、多品类集成线缆定制的领航者 在当今这个多元化、个性化的时代,定制化产品和服务越来越受到市场的青睐。精工电联作为高科技智能化产品及自动化设备专用连接线束和连接器配套服务商,致力于为高科技行…

怎么选择通配符证书?

通配符SSL证书又叫泛域名SSL证书(Wildcard Certficates),通配符SSL证书可以保护一个域名下同级子域名,不限制该级子域名的数量,且添加新的该级子域名无需重新审核和另外付费,可以节省大量的时间和成本。 一…

QFormLayout 背景色设置不成功

(图中的colour 拼错了) layout 一定要放在QWidget 里面,然后设置QWidget 的背景色就好了

【C++】C++中的继承

目录 介绍: 一,继承的访问权限 二,基类和派生类对象赋值转换 三,继承中的作用域 四,派生类的默认成员函数 1,构造函数 2,析构函数 3,拷贝构造和赋值运算符 五,继…

GitCode配置ssh

下载SSH windows设置里选“应用” 选“可选功能” 添加功能 安装这个 坐等安装,安装好后可以关闭设置。 运行 打开cmd 执行如下指令,启动SSH服务。 net start sshd设置开机自启动 把OpenSSH服务添加到Windows自启动服务中,可避免每…

java中实体pojo对于布尔类型属性命名尽量别以is开头,否则 fastjson可能会导致属性读取不到

假如我们有一个场景,就是需要将一个对象以字符串的形式,也就是jsonString存到一个地方,比如mysql,或者redis的String结构。现在有一个实体,我们自己创建的,叫做CusPojo.java 有两个属性是布尔类型的&#x…

STM32引脚重定义问题

最近在搞资源管理,发现有些引脚不能用 比如这个PE引脚。我想用他输出PWM,但是不能用,我也重定义了,还是不能用。回去翻看了技术手册。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //重映射引脚功能,需…

NoSQL 数据库管理工具,搭载强大支持:Redis、Memcached、SSDB、LevelDB、RocksDB,为您的数据存储提供无与伦比的灵活性与性能!

NoSQL 数据库管理工具,搭载强大支持:Redis、Memcached、SSDB、LevelDB、RocksDB,为您的数据存储提供无与伦比的灵活性与性能! 【官网地址】:http://www.redisant.cn/nosql 介绍 直观的用户界面 从单一应用程序中同…

String 必知必会底层逻辑

String 是不可变的 String 类中使用 final 关键字修饰字符数组来保存字符串 public final class String implements java.io.Serializable, Comparable<String>, CharSequence {private final char value[];//... }final关键字的作用&#xff1a; 不可变性&#xff1a…

openai DALL-E 3 论文 提升图像生成的关键:更好的图像描述

摘要 我们展示了通过训练高度描述性的生成图像标题&#xff0c;可以显着改善文本到图像模型的提示跟随能力。 现有的文本到图像模型在跟随详细的图像描述方面存在困难&#xff0c;经常忽略单词或混淆提示的含义。 我们假设这个问题源于训练数据集中存在嘈杂和不准确的图像标…

人工智能|深度学习——基于对抗网络的室内定位系统

代码下载&#xff1a; 基于CSI的工业互联网深度学习定位.zip资源-CSDN文库 摘要 室内定位技术是工业互联网相关技术的关键一环。该技术旨在解决于室外定位且取得良好效果的GPS由于建筑物阻挡无法应用于室内的问题。实现室内定位技术&#xff0c;能够在真实工业场景下实时追踪和…

w29pikachu-ssrf实例

实验环境 php&#xff1a;7.3.4nts apache&#xff1a;2.4.39 浏览器&#xff1a;谷歌实验步骤 ssrf&#xff08;curl&#xff09; 打开ssrf(curl) 点击文字&#xff0c;跳转404页面&#xff0c;从反馈信息来看是找不到对应的页面。 查看源码&#xff0c;发现有个RD变量影…

【Flink网络通讯(一)】Flink RPC框架的整体设计

文章目录 1. Akka基本概念与Actor模型2. Akka相关demo2.1. 创建Akka系统2.2. 根据path获取Actor并与之通讯 3. Flink RPC框架与Akka的关系4.运行时RPC整体架构设计5. RpcEndpoint的设计与实现 我们从整体的角度看一下Flink RPC通信框架的设计与实现&#xff0c;了解其底层Akka通…

利用nbsp设置空格

想要实现上面效果&#xff0c;一开始直接<el-col :span"8" >{{ item.name }} </el-col> 或者<el-col :span"8" >{{ item.name }}</el-col>或者<el-col :span"8" >{{ item.name }}</el-col> 都无…

深入浅出JVM(三)之HotSpot虚拟机类加载机制

HotSpot虚拟机类加载机制 类的生命周期 什么叫做类加载? 类加载的定义: JVM把描述类的数据从Class文件加载到内存,并对数据进行校验,解析和初始化,最终变成可以被JVM直接使用的Java类型(因为可以动态产生,这里的Class文件并不是具体存在磁盘中的文件,而是二进制数据流) 一个…

善于利用GPT确实可以解决许多难题

当我设计一个导出Word文档的功能时&#xff0c;我面临了一个挑战。在技术选型时&#xff0c;我选择了poi-tl这个模板引擎&#xff0c;因为在网上看到了很多关于它的推荐。poi-tl可以根据模板快速导出Word文档。虽然之前没有做过类似的功能&#xff0c;而且项目中也没有用过&…