学习笔记之SOCKET网络编程之二

矩阵束(Matrix Pencil)入门:从通信系统到控制理论,它为何是建模利器? 本文深入探讨矩阵束(Matrix Pencil)在通信系统与控制理论中的关键作用,揭示其作为复杂系统建模利器的独特价值。从MIMO系统的多径干扰分析到电力系统稳定性判据,矩阵束通过`A-λB`方程求解提供精准建模方案,显著提升5G通信和工业控制等领域的性能表现。 阅读详情
1.sendto()和recvfrom()函数
Sendto()和recvfrom()函数用于在无连接的数据报套接字方式下进行数据发送和接收.

sendto()函数
定义:int sendto(int s,void *msg,int len,unsigned int flags,struct sockaddr *to, int tolen);
在发送数据时.由于本地端并没有与远程机器建立一个连接.所以在用sendto()发送数据时我们要告诉它把数据发送到哪里?也就是告诉sendto()发送数据的目的地.
所以它比send()函数多了两个参数.
参数 "struct sockaddr* to"用来告诉它发送数据目的地.包括目标机器的IP和端口等信息.
参数 "int tolen"是struct sockaddr结构的大小.
除此之外其它的参数与send()函数完全相同.
函数成功返回实际发送数据的长度.失败返回-1.

recvfrom()函数
定义:int recvfrom(int s,void *buf,int len,unsigned int flags,sockaddr*from,int *fromlen);
因为是利用数据报套接字传送的数据.所以并没有连接.所以recvfrom()在收到数据后需要知道数据到底是谁发来的?在这里称为"源".所以它比recv()函数多了两个参数.
参数from用来记录源机器的地址信息.包括IP地址和端口等信息.
参数fromlen同样是struct sockaddr结构的大小.
其它参数与recv()函数完全相同.
函数成功时返回实际收到的数据长度.失败返回-1.

2.套接字的关闭.
当我们完成通讯后我们需要把套接字关闭.从而释放资源.
关闭套接字的操作通过调用close()函数来实现.
不管是有连接的流式套接字还是没有连接的数据包式的套接字.只要任何一端调用了close()函数关闭了套接字.都将无法再进行通讯.
另外还有一个函数就是shutdown().它允许你将一定方向上的通讯关闭.当然也可双向通讯都关闭.
也就是说shutdown()函数可以让某一端只接收数据.或者只发送数据.
定义:int shutdown(int s,int how);
参数s是我们将要操作的套接字.
参数how是具体的操作方式.
A.为0时表示不允许接收数据
B.为1时表示不允许发送数据
C.为2时表示不允许接收和发送数据(双向通讯都将关闭,与调用close()函数效果一样.)
函数成功时返回0失败时返回-1.

3.其它.
getpeername()函数.
功能:它用来在有连接的流式套接字中获取对方的地址信息.(包括IP地址和端口)
定义:int getpeername(int s, struct sockaddr *addr, int *addrlen);
参数addr用来存放获取的地址信息.
函数失败返回-1.

gethostname()函数.
功能:它用来获取本机的名字.
定义:int gethostname(char *hostname, size_t len);
参数hostname是一个字符类型的缓冲区.它用来保存本机名字
参数len是缓冲区的长度.
函数成功时返回0.失败时返回-1.

gethostbyname(char*name)函数.
功能:返回由参数name指定的机器的地址信息
定义:struct hostent *gethostbyname(const char *name);
参数name可以是用gethostname()函数获取的机器名字
函数成功返回一个指向struct hostent结构体的指针.失败返回NULL

另:此函数返回的是一个struct hostent结构指针.该结构就包含了一个机器的地址信息
该结构的定义:
struct hostent
{
   char *h_name;                   //地址的正式名称
   char **h_aliases;               //空字节 地址的预备名称的指针
   int h_addrtype;                 //地址的类型.WINDOWS中通常为AF_INET
   int h_length;                   //地址的长度.以位来计算(不是以字节来计算)
   char **h_addr_list;             //零字节 主机网络地址指针.(网络字节顺序)
#define h_addr  h_addr_list[0]       //h_addr_list中的第一地址
};


4.关于阻塞与非阻塞.

阻塞.
简单的说阻塞就是当你调用accept(),send()或者是recv()等过程后.程序必须要等待一个返回结果程序才会继续执行下去.在这种情况下,如果你的程序是单线程的.那么你的程序就会完全挂起.

非阻塞.
而非阻塞正好相反.非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回.

习惯上也称之为同步阻塞和异步非阻塞.


在默认情况下套接字都是阻塞模式的.如果要改变这个设置就要调用fcntl()函数.

fcntl()定义如下:
#include <fcntl.h>
int   fcntl(int  s,int  cmd,  .../* int arg */);
参数s是我们将要设置的套接字.
参数cmd有多种形式.在这里一般设置为F_SETFL.
第三个参数总是一个整数.在此处只需要设置成O_NONBLOCK(表示非阻塞模式)

注意:在windows下的socket编程中.是用iooctlsocket()函数来实现fcntl()函数的功能的.
它的定义如下:
int ioctlsocket(int s,long cmd,u_long *argp);
功能:控制套接字的模式.
参数s是将要操作的套接字.
参数cmd是对套接字的操作方式.
参数argp指向cmd命令所带参数的指针.

参数cmd支持下列几种命令:
A.FIONBIO允许或禁止套接字s的非阻塞模式.参数argp指向一个无符号长整型.如果要允许非阻塞模式则将参数argp设成非零.如果要禁止非阻塞模式(也就是阻塞模式)则将参数argp设成零即可.
注:一个套接字进行了WSAAsyncSelect()操作.它是套接字的一种模式,它将套接字自动设置成非阻塞模式.则任何用试图ioctlsocket()来重新设置套接成阻塞模式的操作都将失败.必须先调用WSAAsyncSelect()来禁止WSAAsyncSelect后才可以.关于WSAAsyncSelect()请查阅其它资料.
B.FIONREAD确定套接字s自动读入数据量.参数argp此时用来存放ioctlsocket()的返回值.如果套接字是SOCKET_STREAM类型(即流式套接字)则FIONREAD返回一次在recv()中所接收到的所有数据量.(即数据长度).这通常与套接字中排队的数据总量相同.如果套接字是SOCK_DGRAM类型.则FIONREAD返回套接字上排队的第一个数据报的大小.
还有一些其它的命令.略.

函数调用成功返回0.失败返回-1.

从系统性能上看,用非阻塞的socket效率和性能更高,但是编程更复杂,特别是当你使用事件或者消息的时候,但是,你可以通过多个工作线程管理多个socket连接,效率非常高,不需要每个工作线程只管理一个socket连接. 用阻塞的方式比较简单,但当较多客户端时消耗系统资源太多.
其大概思想是建立一个线程池,当有socket的事件需要处理时,从线程池中取一个线程来执行,执行完,将线程归还到线程池中.
每个socket连接的时间较长,不断的与服务器交互.每个连接的socket并不是每时每刻都在收发数据.收发数据是断断续续的.这种情况就很适合于上面的方法.

简单的讲同步阻塞常用于连接较少流量较大的地方.非阻塞则刚好相反.用于连接较多.流量较小的地方.
如果要采用阻塞模式.并且要同时处理多个连接.就只能运用多线程来处理.

多路同步.
假设有一台服务器.它一边要进行监听是否有连接到来,还要在其它已经完成的连接上接收数据.也就是accept()和recv()两个函数的调用.当你在调用accept()时遇到阻塞该怎么办.前提是你并没有调用
fcntl()函数把套接字设置非阻塞模式.这时你就可以调用select().它让你可以同时监视多个套接字.它可以告诉你.哪个套接字准备读,哪个套接字准写,哪个套接字发生了意外.

select()函数的定义如下:
int select(int nums,fd_set*reads, fd_set*writes,fd_set *excepts,timeval *timeout);

在讲解select()函数之前我们先讲一下fd_set.
它表示一个集合.具体的讲是一个文件描述符的集合.在此例中都把它理解为套接字描述符.
在Unix中一切都是文件.包括输入设备键盘.硬盘上的文件.还有专门用于网络传输的socket(套接字)等等.所以.在这里都把它当作是socket套接字.
那么文件描述符或者是套接字描述符就好比是WINDOWS下面的句柄.

fd_set的定义如下:
struct fd_set
{
        u_int   fd_count;               /* how many are SET? */
        SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */
};

对这些集合的操作都是通过一些特定的宏来完成的.
    FD_ZERO(fd_set *set)          //清除一个文件描述符集合
      FD_SET(int fd, fd_set *set)   //把fd添加到集合set中
      FD_CLR(int fd, fd_set *set)   //从集合set中移去fd
      FD_ISSET(int fd, fd_set *set) //测试fd是否在集合set中

现在再来说说select()函数,以及它的用法.
该函数的功能就是用来等待套接字(这里只讨论套接字)状态的改变.
参数nums代表最大的套接字描述符加1.
参数reads,writes和excepts是套接字描述符集合,用来回传该套接字描述符的读,写或例外的状况.
参数timeout指向一个timeval结构.它用来设定select等待的时间.可以设置到微秒级.1秒等于1000毫秒.1毫秒等于1000微秒.虽然可以精确到1微秒.但这只是理想的.实际上跟系统还有硬件有关.
timeval结构的定义如下:
struct timeval
{
   int tv_sec;   /* 秒 */
   int tv_usec;  /* 微秒 */
};

当然你可以将参数timeout设置成NULL,那么它将永远不会超时.
成功返回套接字描述状态改变的个数,如果返回0表示在套接字描述符状态改变前已经超过参数timeout设定的时间.当有错误发生时则返回-1.此时参数reads,writes,execepts和timeout的值变得不可预测.
同时有错误发生时,它会设置全局错误变量.常见错误有下面几种.

EBADF 套接字描述符无效或该套接字已关闭
EINTR 此调用被信号所中断
EINVAL 参数n 为负值
ENOMEM 核心内存不足

select()函数的常见用法.

//============
    ......
sockfd = socket(AF_INET, SOCK_STREAM, 0); //获取一个套接字
         ......
fs_set readset; //定义套接字集合,用于查看读状态
FD_ZERO(&readset); //对该集合进行清除操作.
timeval  out; //创建一个timeval结构
out.tv_sec=5; //设定等待秒数为5秒
out.tv_usec=1000*500; //设定等毫秒数为500毫秒
//总的等待时间为5秒+500毫秒.
select(sockfd+1,&readset,NULL,NULL,&out); //select()函数的调用.
if(FD_ISSET(sockfd,readset))//进行判断
    ......
//=============



5.socket编程的最后一个问题
这也是socket编程中的第一个问题.如果你是在windows下面编程的话.

在windows下面进行socket编程我们首先要对socket进行初始化.这时就要用到WSAStartup()函数.
在windows中要调用所有的socket函数之前.我们必须先调用WSAStartup()函数
其定义如下:
int WSAStartup(WORD wVer,WSADATA* lpWSAData);
参数wVer指明可使用的windows socket的版本号.高位字节标明副版本号.低位字字指明主版本号.
参数lpWSAData是指向WSADATA结构的指针.用来接收windows socket实现的细节.
成功时返回0失败返回错误代码.

这里将用MAKEWORD()宏.

MAKEWORD(a,b)它的作用是把a和b组成一个WORD值.
其中第一个参数a是高8位的值.第二个参数b是低8位的值.
我们就是用它来把windows socket的版本号放入WSAStartup()函数的.

例程:
//=====================
WORD sver=MAKEWORD(1,1);//设置socket版本号为1.1
WSADATA wsda;//创建WSADATA结构
if(WSAStartup(sver,&wsda)==0)//调用WSAStartup函数初始化socket
{
    //调用成功.初始化成功
}
//=====================

另外一个函数.它是windows socket编程中的最后一个问题.
WSACleanup()函数.它是终止windows socket的调用.注销windows socket.释放资源.
任何打开的并已建立连接的SOCK_STREAM流式套接字.在调用WSACleanup()时会重置.而已经由close()关闭却仍有要发送而未发送的数据的套接字则不会受影响.该数据仍要发送.
通常.WSACleanup()函数与WSAStartup()函数应成对出现.也就是说对于一个进程的每一次WSAStartup()调用.必须有一个WSACleanup()调用.
但是只有最后一个WSACleanup()调用才会做实际的清除工作.前面的WSACleanup()调用仅仅将windows socket DLL中的内置引用计数递减1.
一般情况下,为了确保WSACleanup()调用了足够的次数.可以在最后用一个循环来不断的调用WSACleanup()函数.直到返回WSANOTINITIALISED为止.
该函数的定义:
int WSACleanup ( void );
函数成功返回0.失败返回-1.同时会设置全局错误变量.
常见的几种错误代码.
A.WSANOTINITIALISED使用本函数之前没有一次成功的WSAStartup()调用.简单的讲.它就是说.前面已经没有WSAStartup()调用了.在这里可以不需要再调用WSACleanup()函数来释放资源了.
B.WSAEINPROGRESS一个阻塞的windows socket操作正在进行.简单的讲.它就是说你正准备注销的这个套接字中某一个操作(比如recv())遇到了阻塞.


<全文完>


 来自: http://blog.sina.com.cn/s/blog_56ea069101000bxm.html
MATLAB与图像处理(一):图像中结构张量的求法(Structure Tensor) 1.结构张量的作用:       能够区分图像中的平坦区域,边缘,角点; 2.图像中的结构张量的定义    1)是一个矩阵;    2)与图像的水平,垂直梯度有关,定义如下: 在MATLAB中,可以用如下语句求解:[Ix,Iy]=gradient(Image); 3)求出结构张量矩阵的行列式,和迹(矩阵对角线之和)   行列式:K=det(E);   迹:   阅读详情

相关推荐

告别 RPA 和 Selenium,MCP + Playwright 成为自动化开发新宠!

摘要: 随着数字化转型加速,传统自动化工具(如RPA和Selenium)在复杂场景中暴露出开发成本高、灵活性不足等问题。新一代解决方案MCP(Model Context Protocol)与Playwright的结合,通过AI与自动化的无缝对接,实现了智能化的任务处理。MCP支持自然语言交互和上下文感知,开发者无需编写复杂代码即可生成自动化脚本;Playwright则提供多浏览器支持、高性能和易用性。二者结合显著提升开发效率,使自动化更智能、灵活。文章还对比了VS Code与Trae中配置Playwrigh

我先测了 2209

linux send 阻塞方式,关于send和sendto阻塞和非阻塞模式的底层细节

对于sendto,Linux 内核最后会调用udp_sendmsg,大概的调用堆栈是udp_sendmsgsecurity_socket_sendmsg__sock_sendmsgsock_sendmsgsendto在sento里面,会根据socket的模式把一个标志传递给内核:if (sock->file->f_flags & O_NONBLOCK)flags |= MSG_...

weixin_39640543的博客 1960

QoderWake 与 Qoder 工具生态详解

Qoder CLIQoder SDKQoderWake谁在用你(开发者)你的程序你的数字员工谁在跑你的终端会话你的应用进程Daemon 后台进程什么时候跑你启动时你的代码调用时7×24 持续运行怎么触发键盘输入函数调用定时/事件/API/IM有记忆吗会话级 + 文件无多层持久记忆能协作吗Subagent多 Waker + IM 群组核心价值编码效率集成灵活性自主生产力一句话总结。

驽马不舍 968

阻塞socket 和非阻塞socket的区别(浅显易懂版)

对于这个问题,我们要先弄清什么是阻塞/非阻塞。阻塞与非阻塞是对一个文件描述符指定的文件或设备的两种工作方式。阻塞的意思是指,当试图对该文件描述符进行读写时,如果当时没有东西可读或者暂时不可写,程序就进入等待状态,直到有东西可读或者可写为止。非阻塞的意思是,当没有东西可读或者不可写时,读写函数就马上返回,而不会等待。现在来理解什么是阻塞socket,什么是非阻塞socket。

qq_56734304的博客 2383

C# ArcGIS Engine二次开发——实现“加载shp文件”

private void AddShpDataToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog OpFileDialog=new OpenFileDialog();//OpenFileDialog:打开文件对话框 OpFileDialog.Title="添加矢量数据"; OpFileDialog.Filter="(*.shp)|*.shp";//filter:过滤器;"(*.shp)|*.shp"

weixin_42191203的博客 5254

ComfyUI工作流换脸节点报错ReActorFaceSwap

找到自己ComfyUI安装目录的custom_nodes下是否有这个comfyui-reactor-node-main。大家在借鉴别人工作流进行AI换脸的时候,如果遇到ReActorFaceSwap报错提示,莫慌,看我的,两步解决问题。这里千万注意不要嵌套文件夹,保证点击去这个文件就可以看到内置的配置文件!找到自己ComfyUI安装目录的facerestore_models。如果有这个文件,直接跳过,去下一步。如果没有,可以去Git官网下载。

qq_70810809的博客 9016

Linux 网络编程之 TINY 程序

在tiny程序中从零开始学习web服务程序

df12138的博客 1846

TwinCAT3 实时核异步通信:基于ADS的C++ Server/Client数据交换实战解析

本文深入解析了在TwinCAT3实时核中,如何利用ADS协议实现C++ Server与Client之间的异步数据交换。文章从核心概念入手,详细阐述了实时核、ADS通信及异步机制,并通过实战步骤指导环境搭建、路由配置、Server端服务创建与Client端请求发起,重点剖析了Req/Ind/Res/Con异步回调模型,旨在帮助开发者构建高效、非阻塞的实时工业控制应用。

purple的博客 469

Socket网络编程学习笔记

Socket网络编程学习笔记    一、IP地址操作类       1、IPAddress类       a、在该类中有一个 Parse()方法,可以把点分的十进制IP表示转化成IPAddress类,方法如下:       IPAddress address = IPAddress.Parse(“192.168.0.1”);        b、IPAddress提供4个只读字段

luyuncsd123的专栏 1715

QGIS基于快鸟(QuickBird)影像统计小麦种植面积

​01数据情况 本次选用某地4月份快鸟(QuickBird)影像为例,使用QGIS演示提取小麦播种情况,并按照200米*200米分区计算种植面积的过程。 注:本文对应的操作视频作为今天第二篇推送同时发布,习惯看视频的朋友可以点击观看。 附数据压缩包: 链接:https://pan.baidu.com/s/1JVUS8uAOR61RxC1n9Or9_w 提取码:qgis 含快鸟影像QB_subset.tif和200*200米分区矢量图层200Mgrid.shp。 ...

QGISClass的博客 1979

基于深度学习的商品标签识别系统:UI界面 + YOLOv8/v7/v6/v5代码 + 训练数据集

基于YOLO系列模型的商品标签识别系统能够有效解决商品信息提取的自动化问题。通过合理的数据集准备、模型训练和UI设计,我们可以实现一个功能强大的商品标签识别系统。希望本文提供的内容能够为大家提供有价值的帮助。

YOLO 475

SOCKET网络编程学习笔记

SOCKET网络编程学习笔记

gghhb12的博客 1262

基于八叉树的k近邻搜索

在八叉树中,每个节点都表示一个正方体的体积元素(体素),并且每个节点都有八个子节点(在不为空的情况下)。搜索最近邻点:一旦确定了查询点在八叉树中的位置,就可以开始搜索最近邻点了。搜索过程通常从查询点所在的叶节点开始,并逐步扩展到相邻的叶节点和父节点,直到找到k个最近邻点为止。k近邻搜索的目标是在给定的点云数据中,找到一个查询点的k个最近邻点。定位查询点:在搜索过程中,首先需要确定查询点在八叉树中的位置。返回结果:最后,搜索算法会返回找到的k个最近邻点的索引和它们与查询点之间的距离。

twnkie的博客 674

java学习笔记————Socket网络编程小总结

**对于网络编程其实就相当于,在生活中人与人之间的交流,提问的一方作为用户端,回答问题的一方作为服务器端** 接下来我就和大家我学习socket网络编程所学到的知识

Belief的博客 497

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Linux学习笔记——网络编程socket篇

Socket 是一个编程接口 是一种特殊的文件描述符 (everything in Unix is a file) 并不仅限于TCP/IP协议 面向连接 (Transmission Control Protocol - TCP/IP) 无连接 (User Datagram Protocol -UDP 和 Inter-network Packet Exchange - IPX)

m0_64432298的博客 1810

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

网络编程学习笔记一:Socket编程

“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型有哪些?还有

程书画的 BLOG 18万+

JavaSE学习笔记 基于Socket的TCP网络编程

网络编程1.网络编程的基本知识回顾1.1 C/S与B/S结构1.2 网络编程的三要素解析1.2.1 IP地址1.2.2 端口号1.2.3 网络协议2.Socket通信 前面我们对网络编程的基本知识做了一定的了解,下面将正式进入网络编程之中。 1.网络编程的基本知识回顾 1.1 C/S与B/S结构 应用程序架构分为两种: 1.C/S架构:C/S(Client/Server)即客户端/服务器 2.B/S架构:B/S(Browser/Server)即浏览器/服务器. C/S架构是一种比较早的软件架构,主要用

qq_41537102的博客 342

python学习笔记2:socket网络编程

如何使用socket进行网络编程

mminions的博客 1121

Linux Socket 网络编程学习笔记

Linux Socket 网络编程学习笔记

ouynagda的博客 259

【学习笔记】简单的socket网络编程实例

TCP的三次握手(图片来自百度百科) TCP的四次分手(图片来自百度百科) 单向交互套结字 服务端 /* * Author: xusongqi@live.com * * Created Time: 2014年03月19日 星期三 17时29分14秒 * * FileName: sock_server.c * * Descript

许嵩奇 1563

网络编程学习笔记:Socket编程

一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型有哪些?还有s...

qq_42920625的博客 256

【Java学习笔记】基于Socket的TCP网络编程和UDP网络编程

一、基于Socket的TCP网络编程 TCP协议的特点: 使用TCP协议前,须先建立TCP连接,形成传输数据通道 传输前,采用“三次握手” 方式,点对点通信, 是可靠的 TCP协议进行通信的两个应用进程:客户端、 服务端。 在连接中可进行大数据量的传输 传输完毕,需释放已建立的连接, 效率低 客户端Socket 客户端程序的工作过程包含以下四个基本的步骤: 创建 Socket: 根据指定服务...

ENKU1的博客 433

Windows Socket网络编程学习笔记一

作者:朱金灿 来源:blog.youkuaiyun.com/clever101 如何理解Windows Socket? 我的理解:Windows Socket相当于Windows平台上两个网络实体开辟的一条通信通道,这条通信通道的实现细节对网络双方是不可见的(呵呵,你就知道它是Windows制造)。通过这条通道,网络双方可以传输各种数据。 你可能...

ladymaidu 81
上一篇: linux下socket connect超时设置
下一篇: 学习笔记之SOCKET网络编程
tinyhare
博客等级 码龄15年 11粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值