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

news2025/3/13 0:09:36

套接字编程

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);
    }
}

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

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

相关文章

【精选】Java面向对象进阶——接口细节:成员特点和接口的各种关系

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 …

STM32学习笔记(七) —— DMA传输(MTM)

DMA,全称是Direct Memory Access(直接内存访问)。可以在存储器和存储器之间或者外设和存储器之间传输数据,而不需要CPU的干预,这样可以节省CPU的资源,提高工作效率。 1.功能框图 STM32F103RCT6有两个DMA控…

怎样让MCU/SFU视频会议ovmedia 接入GB28281监控视频参会互动

在国内视频应用对GB监控接入是常规操作,很多系统需要接入监控视频交互处理。我们以ovmedia视频会议为例做一个接入互动。 GB28181协议在流媒体系统较为普及,我们以开源SRS系统对接监控端再接入会议(也可以用商用GB流平台,操作基本…

嵌入式——EEPROM(AT24C02)

目录 一、初识AT24C02 1. 介绍 2. 引脚功能 补: 二、AT24C02组成 1. 存储结构 2. AT24C02通讯地址 3. AT24C02寻址方式 (1)芯片寻址 (2)片内子地址寻址 三、AT24C02读写时序 1. 写操作 (1&…

C语言——从头开始——深入理解指针(1)

一.内存和地址 我们知道计算上CPU(中央处理器)在处理数据的时候,是通过地址总线把需要的数据从内存中读取的,后通过数据总线把处理后的数据放回内存中。如下图所示: 计算机把内存划分为⼀个个的内存单元,每…

人机交互新研究:MIT开发了结合脑电和眼电的新式眼镜,与机器狗交互

还记得之前的AI读心术吗?最近,「心想事成」的能力再次进化, ——人类可以通过自己的想法直接控制机器人了! 来自麻省理工的研究人员发表了Ddog项目,通过自己开发的脑机接口(BCI)设备&#xff…

16.Qt 工具栏生成

目录 前言: 技能: 内容: 1. 界面添加 2. 信号槽 功能实现 参考: 前言: 基于QMainWindow,生成菜单下面的工具栏,可以当作菜单功能的快捷键,也可以完成新的功能 直接在UI文件中…

django中事务和锁

目录 一:事务(Transactions) 二:锁 在Django中,事务和锁是数据库操作中的两个重要概念,它们用于确保数据的完整性和一致性。下面我将分别解释这两个概念在Django中的应用。 一:事务&#xff…

值得收藏的的适用于 Windows 11 的免费数据恢复软件榜单

终于要说到Windows 11了,有太多令人惊叹的功能,让人跃跃欲试。但是,在升级到 Windows 11 或使用 Windows 11 时,人们可能会因计算机问题而导致文件被删除或丢失。这就是为什么需要 Windows 11 的免费文件恢复的原因。这是适用于 W…

vscode右键菜单栏功能说明

本文主要介绍在vscode中的python代码文件中,单击鼠标右键出现的菜单栏功能。部分功能可能与安装插件相关,主要用于个人查阅。 单击右键菜单栏如下: GO to xx类型命令 “Go to Definition”、“Go to Declaration”、"Go to Type Defin…

相机图像质量研究(31)常见问题总结:图像处理对成像的影响--图像差

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

什么原因导致百度百科建立一直审核不通过?

百科词条对网络营销实在是太重要了,不管是个人还是企业想在网上开展业务,都必要建立百科词条。自己动手编辑百科词条,搞个几十次也审核不过的情况比比皆是。 为什么百度百科总是审核不通过?百度官方发表过声明表示百度百科词条是人…

租用一个服务器需要多少钱?2024阿里云新版报价

2024年最新阿里云服务器租用费用优惠价格表,轻量2核2G3M带宽轻量服务器一年61元,折合5元1个月,新老用户同享99元一年服务器,2核4G5M服务器ECS优惠价199元一年,2核4G4M轻量服务器165元一年,2核4G服务器30元3…

深入剖析跨域请求发送两次的原因及解决方案(下)

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【大厂AI课学习笔记】【2.1 人工智能项目开发规划与目标】(7)特征工程的基本方法

今天来学习特征工程的基本方法。 基本方法包括:特征选择(Feature Selection)、特征提取(Feature Extraction)和特征构建(Feature Construction)。 一、特征选择(Feature Selection&a…

基于飞腾ARM+FPGA国产化计算模块联合解决方案

联合解决方案概述 随着特殊领域电子信息系统对自主创新需求的日益提升,需不断开展国产抗恶劣环境计算整机及模块产 品的研制和升级。特殊领域电子信息系统的自主创新,是指依靠自身技术手段和安全机制,实现信息系统从硬 件到软件的自主研发…

计算机服务器中了_locked勒索病毒怎么办?Encrypted勒索病毒解密数据恢复

随着网络技术的不断发展,数字化办公已经成为企业生产运营的根本,对于企业来说,数据至关重要,但网络威胁无处不在,近期,云天数据恢复中心接到很多企业的求助,企业的计算机服务器遭到了_locked勒索…

Codeforces Round 926 (Div. 2) C. Sasha and the Casino (Java)

Codeforces Round 926 (Div. 2) CC. Sasha and the Casino (Java) 比赛链接:Codeforces Round 926 (Div. 2) C题传送门:C. Sasha and the Casino 题目:C. Sasha and the Casino **Example ** input 2 1 7 2 1 1 2 3 15 3 3 6 4 4 5 5 4 7…

⭐北邮复试刷题429. N 叉树的层序遍历(按层入队出队BFS)

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

面试经典150题——螺旋矩阵

"The harder the conflict, the more glorious the triumph." - Thomas Paine 1. 题目描述 2. 题目分析与解析 2.1 思路一 看到题目,先仔细观察矩阵,题目要求我们给出顺时针遍历的结果即可,我们根据矩阵可以看出,首…