网络编程之流式套接字

流式套接字(SOCK_STREAM)是一种网络编程接口,它提供了一种面向连接的、可靠的、无差错和无重复的数据传输服务。这种服务保证了数据按照发送的顺序被接收,使得数据传输具有高度的稳定性和正确性。通常用于那些对数据的顺序和完整性有严格要求的应用。通常由传输控制协议(TCP)来实现。TCP协议通过建立连接、数据分包的编号和确认、以及重传机制等方式来确保数据的可靠传输。尽管这种服务提供了高度的可靠性,但它也可能导致较高的网络资源占用率。

 客户端代码

//客户端
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")//告诉链接器将 ws2_32.lib 这个库文件链接到可执行文件中,以便使用 Windows Sockets API
int main(int argc, char* argv[])
{
WSADATA wsaData;
SOCKET sockClient;//客户端Socket
SOCKADDR_IN addrServer;//服务端地址
WSAStartup(MAKEWORD(2,2),&wsaData);
sockClient=socket(AF_INET,SOCK_STREAM,0);//创建一个TCP类型的流式Socket。AF_INET指定使用IPv4协议

//定义要连接的服务端地址
addrServer.sin_family=AF_INET;
addrServer.sin_addr.s_addr=inet_addr("127.0.0.1");//127.0.0.1是本地环回地址,因为这里客户端和服务端在同一个主机上
addrServer.sin_port=htons(6000);//连接端口6000

//连接到服务端
connect(sockClient,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));
//发送数据
char message[30]="Hello Socket!";//准备要发送的消息,字符串长度限制在 30 字节以内。
send(sockClient,message,strlen(message)+1,0);//要发送的消息的长度,包括字符串结尾的空字符,以确保接收方能正确地识别字符串的结束0。


//关闭socket
closesocket(sockClient);
WSACleanup();
printf("success!\n");//简单的打印输出,表示程序正常运行
return 0;
}

服务端代码 

//服务端
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

int main(int argc, char* argv[]) {
    WSADATA wsaData;
    SOCKET sockServer;
    SOCKADDR_IN addrServer;
    SOCKET sockClient;
    SOCKADDR_IN addrClient;
    
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    
    sockServer = socket(AF_INET, SOCK_STREAM, 0);
    addrServer.sin_addr.s_addr = INADDR_ANY;

    addrServer.sin_family = AF_INET;
    addrServer.sin_port = htons(6000);//指定服务端的监听端口号为 6000。 
    
    bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));//bind函数将Socket与指定的地址和端口绑定
    listen(sockServer, 5); //开始监听连接请求,5 表示队列中最多可以容纳 5 个待处理的连接请求。
    
    printf("服务器已启动;\n监听中...\n");
    
    int len = sizeof(SOCKADDR);//用于存储客户端地址信息的结构体的大小
    char recvBuf[100];//用于接收客户端发送的消息的缓冲区。

    sockClient = accept(sockServer, (SOCKADDR*)&addrClient, &len);//accept函数接受客户端的连接请求
    recv(sockClient, recvBuf, 100, 0);//接收客户端发送的消息存储在 recvBuf 中。
    printf("%s\n", recvBuf);
    
    closesocket(sockClient);//关闭与客户端的连接套接字
    closesocket(sockServer);//关闭服务端监听套接字
    
    WSACleanup();
    printf("success!\n");//表示正常运行
    return 0;
}

 先运行服务器,开始监听

然后运行客户端

服务器结果如下,收到客户端发来的消息Hello Socket!

套接字函数

1、socket函数:创建一个套接字

socket(AF, type, protocol);

AF:指定套接字使用的地址族,常见的值包括 AF_INET(IPv4 地址族)和 AF_INET6(IPv6 地址族)

type:套接字类型,可选SOCK_STREAM(流式套接字),和 SOCK_DGRAM(数据报套接字)

protocol:指定套接字使用的协议,通常设置为默认0

例如本实验创建一个IPv4 地址族的流式套接字

socket(AF_INET,SOCK_STREAM,0)

2、bind函数:将一个套接字与一个IP地址绑定在一起。

bind(s, sockaddr *name, int namelen)

s:要绑定地址的套接字变量。

name:指向包含地址信息的 sockaddr 结构体的指针。

namelen:name 结构体的长度

客户端套接字在发出连接请求后,由内核自动绑定到一个临时端口和地址上,所以不需要这个函数。而作为服务器,一般是工作在被动连接的方式下,所以必须通过显示的调用bind()将监听套接字绑定到一个端口上,以等待客户端的连接。

例如本实验将套接字sockServer绑定地址为&addrServer上的信息

bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR))

3、listen函数:将指定的套接字设置为监听状态

listen(s, max)

s:要设置为监听状态的套接字变量

max:等待连接队列的最大长度

例如本实验将sockServer设置为监听模式,最多可以同时连接5个客户端

listen(sockServer, 5)

4、connect函数:用于将套接字连接到指定的目标地址

connect(s, sockaddr *name, namelen)

s:请求连接的套接字变量

name: sockaddr 结构体的指针,包含了要连接的目标地址和端口信息

namelen:name 结构体的长度

例如本实验请求连接的套接字是sockClient,要连接的目的地址是&addrServer

connect(sockClient,(SOCKADDR*)&addrServer,sizeof(SOCKADDR))

5、accept 函数:用于接受客户端的连接请求,并创建一个新的套接字来与客户端进行通信。

accept(s, sockaddr *addr, int *addrlen)

s:处于监听状态的套接字

addr:存储客户端地址信息的指针

addrlen:指向一个整数变量的指针,用于存储客户端地址信息的结构体的长度。需要将addrlen设置为 sizeof(struct sockaddr)

例如本实验sockServer处于监听状态,客户端地址为addrClient

sockClient = accept(sockServer, (SOCKADDR*)&addrClient, &len)

6、send函数:向已连接的套接字发送数据

send(s, buf, len)

s:发送数据的套接字变量。

buf:指向要发送数据的缓冲区的指针。

len:要发送的数据的长度(以字节为单位)。

调用 send 函数后,它会将指定长度的数据从缓冲区 buf 发送到套接字 s 所连接的目标。

例如本实验sockClient发送数据长度为strlen(message)+1的数据

send(sockClient,message,strlen(message)+1,0)

7、recv函数:用于接收通过已连接套接字传输的数据

recv(s, buf, len)

s:要接收数据的套接字变量

buf:指向接收数据的缓冲区的指针

len:缓冲区长度,即接收数据的最大长度

例如本实验接收sockClient发到recvBuf缓冲区的信息

recv(sockClient, recvBuf, 100, 0)

8、closesocket函数:用于关闭套接字被关闭的套接字不能再用于任何操作

closesocket(s)

客户端:socket() --> connect() --> send() --> recv() --> close()

服务端:socket() --> bind() --> listen() --> accept() --> recv() --> close()

send函数可以用write函数代替,recv 函数可以用write函数代替,但是send函数和recv函数能在跨平台的网络编程中使用,所以建议使用send和recv以确保更好的可移植性和兼容性。

结构体

1、sockaddr结构体

struct sockaddr {

    unsigned short sa_family; // 地址族,地址的类型,如 AF_INETAF_INET6

    char sa_data[14]; // 地址数据

};

2、sockaddr_in结构体

struct sockaddr_in {

    short sin_family;           // 地址族,通常设置为 AF_INETIPv4

    unsigned short sin_port;    // 端口号,网络字节序

    struct in_addr sin_addr;    // IP地址

    char sin_zero[8];           // 保留字段,通常填充0

};

3、in_addr结构体

struct in_addr {

    unsigned long s_addr;  // 存储 IPv4 地址的 32 位整数,采用网络字节序

};

4、SOCKET结构体

用于声明套接字变量,然后再将这个变量传入套接字函数进行操作

5、WSADATA 结构体

初始化变量,然后将该变量传入WSAStartup()函数,该函数的作用是初始化 Windows Sockets API。告知系统将要使用的套接字库的版本号。如MAKEWORD(2, 2)表示使用版本号为 2.2 的套接字库,程序执行完后使用WSACleanup()函数释放Winsock库的资源

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

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

相关文章

Backend - gitea 首次建库(远端本地)

目录 一、建立远端储存库 1. 进入新增画面 2. 填写储存库名称&#xff08;如book&#xff09;&#xff0c;点击“建立”即可 二、本地关联远端储存库 1. 本地初始化储存库代码 &#xff08;1&#xff09;新建文件夹 &#xff08;2&#xff09;获取远端储存库 2. 本地编写…

Linux:基础IO

回顾C文件接口 stdin & stdout & stderr C 默认会打开三个输入输出流&#xff0c;分别是 stdin, stdout, stderr 仔细观察发现&#xff0c;这三个流的类型都是 FILE*, fopen 返回值类型&#xff0c;文件指针 系统文件I/O 接口介绍 open man open #include <sy…

FCP270 P0917YZ 兼容性如何

FCP270 P0917YZ 是一种现场控制处理器&#xff0c;通常应用于工业自动化和过程控制系统中。 这款现场控制处理器的主要职责是监测和控制多种过程变量&#xff0c;确保系统的正常运行&#xff0c;并且满足生产的要求。以下是关于FCP270 P0917YZ的一些可能用途和特点&#xff1a…

【Java 多线程】从源码出发,剖析Threadlocal的数据结构

文章目录 exampleset(T value)createMap(t, value);set(ThreadLocal<?> key, Object value)ThreadLocalMap和Thread的关系 全貌 ThreadLocal是个很重要的多线程类&#xff0c;里面数据结构的设计很有意思&#xff0c;很巧妙。但是我们平时使用它的时候常常容易对它的使用…

SwiftUI Release 引入的辅助焦点管理

文章目录 前言使用 FocusState 属性包装器高级技巧&#xff1a;专用辅助技术可聚焦字段的高级用法优化体验运行截图总结 前言 SwiftUI Release 引入了强大的新功能&#xff0c;其中之一是辅助焦点管理。 这个新功能使得在SwiftUI中处理辅助技术&#xff08;如 VoiceOver 和 S…

Python程序设计 循环结构(二)

1.斐波那契数列 编写一个能计算斐波那契数列中第x个数的小程序。斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列、 因数学家莱昂纳多斐波那契&#xff08;Leonardoda Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为…

protobuf 从版本 4.24.4 降级到版本 3.19.0

1.查看protobuf版本号&#xff1a; pip show protobuf2.卸载 4.24.4 的版本 pip uninstall protobuf3.安装 3.19.0 的版本 pip install protobuf3.19.04.查看版本是否安装成功 pip show protobuf

STM32通用输入输出

一、GPIO介绍 功能&#xff1a; 输入&#xff08;Input&#xff09;&#xff1a; 浮空:输入没有接上拉和下拉 模拟&#xff1a;输入没有走上拉和下拉走的是模拟输入 上拉&#xff1a;上拉电阻是合上的&#xff0c;接入点为上拉电阻 下拉&#xff1a;下拉电阻是合上的 输…

Cocos2dx-lua ScrollView[三]高级篇

一.概述 本文缩写说明:sv = ScrollView, cell代表ScrollView的一个子节点 本文介绍sv的一种封装类库,来实现快速创建sv,有如下几个优点: 1.item的位置通过参数控制,提高开发效率 2.免去了调用sv的API,提高开发效率 3.分帧创建,提高性能 4.可通过参数控制,复用ite…

uniapp h5 引入阿里云一键登录

参考官方文档: 如何将H5页面接入网页端SDK并一键登录_号码认证服务(PNVS)-阿里云帮助中心 本文主要分享uniapp 对SDK依赖文件的引入 采用npm包引入的方法: 1.下载 // 下载npm资源并添加依赖到package.json npm i aliyun_numberauthsdk_web -S tips: 查看package.json文件,确…

Java毕业设计-基于springboot开发的疫情防控期间外出务工人员信息管理系统-毕业论文+答辩PPT(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1、开发说明2、需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、后台登录2.1管理员功能2.2用户功能2.3采集员功能2.4分析员功能 四、毕设内容和源代码获取总结 Java毕业设计-基…

MySql实战--事务到底是隔离的还是不隔离的

第3篇文章和你讲事务隔离级别的时候提到过&#xff0c;如果是可重复读隔离级别&#xff0c;事务T启动的时候会创建一个视图read-view&#xff0c;之后事务T执行期间&#xff0c;即使有其他事务修改了数据&#xff0c;事务T看到的仍然跟在启动时看到的一样。也就是说&#xff0c…

MySQL安装和配置(超详细)

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;&#x1f468;&#x1f3fb;‍&#x1f393;告别&#xff0c;今天 &#x1f4d4;高质量专栏 &#xff1a;☕java趣味之旅 欢迎&#x1f64f;点赞&#x1f5e3;️评论&#x1f4e5;收藏&#x1f493;关注 &#x1f496;衷心的希…

为什么做秒真问答?秒真问答营销的价值分析

近来&#xff0c;今日头条对部分业务做出调整。一方面是将“头条百科”升级为“抖音百科”&#xff0c;通过“抖音百科”这个新品牌&#xff0c;更好的为今日头条和抖音的内容场景服务。另外一方面则是&#xff0c;推出全新的问答业务“秒真问答”&#xff0c;目前已经在抖音和…

apisix创建https

总结了下apisix 使用https 的问题和方法 1、apisix 默认https 端口是9443 2、apisix 需要上传证书后才可以使用https 否二curl测试会报错 SSL routines:CONNECT_CR_SRVR_HELLO 3、apisix 上传证书方法 我是使用的自签名证书&#xff0c;注意自签名证书的Common Name 要写你…

WPF 多路绑定、值转换器ValueConvert、数据校验

值转换器 valueconvert 使用ValueConverter需要实现IValueConverter接口&#xff0c;其内部有两个方法&#xff0c;Convert和ConvertBack。我们在使用Binding绑定数据的时候&#xff0c;当遇到源属性和目标控件需要的类型不一致的&#xff0c;就可以使用ValueConverter&#xf…

Tickeys for Mac:让每一次敲击都充满乐趣,提升打字体验新高度!

Tickeys for Mac 是一款为 macOS 设计的虚拟键盘音效生成器。它通过模拟机械键盘的声音&#xff0c;为打字和输入操作增添了音效反馈&#xff0c;让用户在使用电脑时感受到更加真实的键盘反馈体验。用户可以根据个人喜好选择不同类型的键盘声音和音效设置&#xff0c;让键盘操作…

嗨购模式:绿色积分引领消费新潮流,实现增值共赢新篇章

随着绿色消费观念深入人心&#xff0c;绿色积分作为新的消费激励方式受到了广大消费者的热烈追捧。在众多消费模式中&#xff0c;嗨购模式凭借其独特的绿色积分融合策略&#xff0c;让消费者在享受绿色消费的同时&#xff0c;也能获得更多实惠与额外收益。 传统的全返机制虽然为…

Docker 部署 Elasticsearch-Filebeat-Kibana

目录 一、简介 1.Elasticsearch: 2.Filebeat: 3.Kibana: 二、工作流程 三、部署 1.创建docker网络 2.启动 elasticsearch 容器 3.创建 kibana 容器 4.客户端安装日志采集器filebeat &#xff08;1&#xff09;docker安装 &#xff08;2&#xff09;rpm安装 四、访…

新品发布|灵雀云重磅推出大模型 LLMOps 平台

自即日起&#xff0c;灵雀云正式推出大模型 LLMOps 平台 Alauda Machine Learning &#xff08;简称 AML&#xff09;&#xff0c;AML在整合传统 MLOps 解决方案的基础之上&#xff0c;为大模型/大语言模型场景提供更强大、更易用的功能。灵雀云意在将AML打造成全面覆盖传统 ML…