【socket编程-06】使用bind()和connect()函数

socket 编程基础(网络编程)-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板 socket编程是一种在Linux下的进程间通信机制,用于不同主机上或同一主机上应用程序之间的通信。它通常采用客户端与服务器的模式进行通信,多个客户端可以同时连接到服务器。开发人员通过调用内核提供的socket接口来开发应用程序,socket作为应用层与TCP/IP协议的中间软件抽象层,简化了开发过程。 socket编程广泛应用于网络程序设计,并且基于BSD socket标准的应用程序可以方便地移植到不同平台。编程接口包括创建套接字的socket()函数、绑定IP地址和端口的bind()函数...... 阅读详情

  声明:本博客所转《socket编程》系列教程来自C语言中文网,本文地址使用bind()和connect()函数,本文仅供学习交流,更多内容请支持原创!


socket() 函数用来创建套接字,确定套接字的各种属性,然后服务器端要用 bind() 函数将套接字与特定的IP地址和端口绑定起来,只有这样,流经该IP地址和端口的数据才能交给套接字处理;而客户端要用 connect() 函数建立连接。

bind() 函数

bind() 函数的原型为:

int bind(int sock, struct sockaddr *addr, socklen_t addrlen);  //Linux
int bind(SOCKET sock, const struct sockaddr *addr, int addrlen);  //Windows

下面以Linux为例进行讲解,Windows与此类似。

sock 为 socket 文件描述符,addr 为 sockaddr 结构体变量的指针,addrlen 为 addr 变量的大小,可由 sizeof() 计算得出。

下面的代码,将创建的套接字与IP地址 127.0.0.1、端口 1234 绑定:

//创建套接字
int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

//创建sockaddr_in结构体变量
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
serv_addr.sin_family = AF_INET;  //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
serv_addr.sin_port = htons(1234);  //端口

//将套接字和IP、端口绑定
bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

这里我们使用 sockaddr_in 结构体,然后再强制转换为 sockaddr 类型,后边会讲解为什么这样做。
sockaddr_in 结构体
接下来不妨先看一下 sockaddr_in 结构体,它的成员变量如下:

struct sockaddr_in{
    sa_family_t     sin_family;   //地址族(Address Family),也就是地址类型
    uint16_t        sin_port;     //16位的端口号
    struct in_addr  sin_addr;     //32位IP地址
    char            sin_zero[8];  //不使用,一般用0填充
};
  1. sin_family 和 socket() 的第一个参数的含义相同,取值也要保持一致。

  2. sin_prot 为端口号。uint16_t 的长度为两个字节,理论上端口号的取值范围为 0~65536,但 0~1023 的端口一般由系统分配给特定的服务程序,例如 Web 服务的端口号为 80,FTP 服务的端口号为 21,所以我们的程序要尽量在 1024~65536 之间分配端口号。

端口号需要用 htons() 函数转换,后面会讲解为什么。

  1. sin_addr 是 struct in_addr 结构体类型的变量,下面会详细讲解。

  2. sin_zero[8] 是多余的8个字节,没有用,一般使用 memset() 函数填充为 0。上面的代码中,先用 memset() 将结构体的全部字节填充为 0,再给前3个成员赋值,剩下的 sin_zero 自然就是 0 了。

in_addr 结构体
sockaddr_in 的第3个成员是 in_addr 类型的结构体,该结构体只包含一个成员,如下所示:

struct in_addr{
    in_addr_t  s_addr;  //32位的IP地址
};

in_addr_t 在头文件 <netinet/in.h> 中定义,等价于 unsigned long,长度为4个字节。也就是说,s_addr 是一个整数,而IP地址是一个字符串,所以需要 inet_addr() 函数进行转换,例如:

unsigned long ip = inet_addr("127.0.0.1");
printf("%ld\n", ip);

运行结果:
16777343

图解 sockaddr_in 结构体

为什么要搞这么复杂,结构体中嵌套结构体,而不用 sockaddr_in 的一个成员变量来指明IP地址呢?socket() 函数的第一个参数已经指明了地址类型,为什么在 sockaddr_in 结构体中还要再说明一次呢,这不是啰嗦吗?

这些繁琐的细节确实给初学者带来了一定的障碍,我想,这或许是历史原因吧,后面的接口总要兼容前面的代码。各位读者一定要有耐心,暂时不理解没有关系,根据教程中的代码“照猫画虎”即可,时间久了自然会接受。

为什么使用 sockaddr_in 而不使用 sockaddr
bind() 第二个参数的类型为 sockaddr,而代码中却使用 sockaddr_in,然后再强制转换为 sockaddr,这是为什么呢?

sockaddr 结构体的定义如下:

struct sockaddr{
    sa_family_t  sin_family;   //地址族(Address Family),也就是地址类型
    char         sa_data[14];  //IP地址和端口号
};

下图是 sockaddr 与 sockaddr_in 的对比(括号中的数字表示所占用的字节数):

sockaddr 和 sockaddr_in 的长度相同,都是16字节,只是将IP地址和端口号合并到一起,用一个成员 sa_data 表示。要想给 sa_data 赋值,必须同时指明IP地址和端口号,例如”127.0.0.1:80“,遗憾的是,没有相关函数将这个字符串转换成需要的形式,也就很难给 sockaddr 类型的变量赋值,所以使用 sockaddr_in 来代替。这两个结构体的长度相同,强制转换类型时不会丢失字节,也没有多余的字节。

可以认为,sockaddr 是一种通用的结构体,可以用来保存多种类型的IP地址和端口号,而 sockaddr_in 是专门用来保存 IPv4 地址的结构体。另外还有 sockaddr_in6,用来保存 IPv6 地址,它的定义如下:

struct sockaddr_in6 { 
    sa_family_t sin6_family;  //(2)地址类型,取值为AF_INET6
    in_port_t sin6_port;  //(2)16位端口号
    uint32_t sin6_flowinfo;  //(4)IPv6流信息
    struct in6_addr sin6_addr;  //(4)具体的IPv6地址
    uint32_t sin6_scope_id;  //(4)接口范围ID
};

正是由于通用结构体 sockaddr 使用不便,才针对不同的地址类型定义了不同的结构体。

connect() 函数

connect() 函数用来建立连接,它的原型为:

int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen);  //Linux
int connect(SOCKET sock, const struct sockaddr *serv_addr, int addrlen);  //Windows

各个参数的说明和 bind() 相同,不再赘述。

深度揭秘!用 DeepSeek 打造超智能电商客服系统全流程 摘要:本文围绕使用 DeepSeek 开发电商智能客服展开详细教程。先介绍前期准备,包括了解 DeepSeek、获取 API 权限与搭建开发环境。接着阐述数据收集预处理,结合电商业务逻辑实现商品与订单信息查询。还提及优化性能的方法,如模型微调、多轮对话管理和错误处理。然后说明了基于 Web 和云平台的部署方案。最后强调持续监控和改进的重要性,通过设置监控指标、收集分析用户反馈来优化系统,助力开发者打造高效电商智能客服。 阅读详情

相关推荐

MT6771 Android13 背光曲线调试与光感数据校准实战

本文详细介绍了MT6771平台在Android 13系统上进行背光曲线调试与光感数据校准的实战经验。针对高亮度环境下背光误调节问题,深入分析了光感数据上报机制,并提供了驱动层配置修改、背光曲线优化及常见问题解决方案,帮助开发者快速定位并解决类似问题。

moon9的博客 287

socket学习一、socket、bind/connect、listen函数详解

Socket本意是插座,在计算机通信领域中被翻译为“套接字”,是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。通过Socket,两台计算机可以通过网络进行信息的传递。

个人工作中学到的专业技术与职业发展知识笔记 3682

单片机通识之UART通信协议(如何用汇编实现)

使用汇编实现UART通信

smart_num_1的博客 996

C++ 使用Socket实现主机间的UDP/TCP通信

服务器端的代码做了跨平台(POSIX和WINDOWS),基于POSIX平台(Linux、Mac OS X、PlayStation等)使用sys/socket.h库,windows平台使用winsock2.h库。 客户端代码因为基本都在windows运行,所以没做跨平台,需要的话你可以参考服务器端代码自己做一下。 文中写的函数原型均为windows平台,部分函数的返回类型或参数类型在POSIX会有不同。

qq_38243831的博客 3907

Qt绘图实战:用QGraphicsItem实现可拖拽箭头连接(附完整代码)

本文详细介绍了如何使用Qt的QGraphicsItem框架实现一个功能完备的可拖拽箭头连接组件。通过核心代码示例,讲解了如何创建自定义图形项、实现智能吸附、碰撞检测以及实时拖拽编辑路径,为构建流程图、拓扑图等专业图形编辑器提供了完整的解决方案。

m2n3b4v5c6的博客 626

ESP32实战指南:SPI驱动ADXL345三轴加速度传感器的精准数据采集与姿态解算

本文详细介绍了如何使用ESP32通过SPI接口驱动ADXL345三轴加速度传感器,实现精准数据采集与姿态解算。从硬件连接到SPI通信优化,再到数据处理和低功耗策略,提供了全面的实战指南。特别适合物联网开发者和硬件工程师参考,帮助快速掌握传感器数据采集技术。

vim8coder的博客 1042

Socket中connect 函数与bind函数有什么区别

函数都是用于网络编程中的套接字操作,但它们的用途和作用略有不同。

xuxuxucq的博客 2035

用Multisim仿真石英晶体振荡电路:从等效模型到频响曲线实战

本文通过Multisim软件,从构建石英晶体等效电路模型入手,详细演示了如何仿真分析其电抗频率特性曲线,并实战搭建与调试皮尔斯振荡电路。文章深入探讨了振荡必须工作在串联与并联谐振点之间感性区的原因,为电子设计者提供了从理论到仿真的完整可视化学习路径。

ik67890123的博客 501

【Socket】Linux下UDP Socket的基本流程以及connect、bind函数的使用(C语言实现)

Socket的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”。Socket通信主要有两个类型:TCP、UDP。TCP通信,是一个有序的、可靠的、面向连接的通信方式。用数据流的方式传递信息。UDP通信,是无连接的、不保证有序到达的、但具有较好的实时性、能够高速传输的通信方式。用数据报的方式传递信息。其中,UDP Socket实时性要求高,可以接受一定的数据错误和丢失。例如在线游戏、音视频聊天等场景。

weixin_44589672的博客 3165

【MATLAB】绘制泽尼克多项式

上次只给了公式没有给代码,很多小伙伴表示不是很认可。今天直接把代码发上来了。

HPC_ZY 5576

YOLOv11低照度目标检测优化方案:基于SCINet可训练预处理主干的全流程实现指南

创建一个新的Python文件,如。

FJN110的博客 188

python bind方法_python – 使用ZMQ PUB与.connect()或.bind()方法有什么区别?

在Python ZMQ发布者/订阅者样本模板中,发布者使用.bind()方法,订阅者使用连接到绑定IP地址的.connect()方法.但是我们可以用另一个替换.bind()和.connect().我的问题是,下面确定的两个案例有什么区别?(在这些情况下两个脚本工作正常)第一种情况,默认情况下:pub1.py:import zmqimport timefrom datetime import dat...

weixin_39821605的博客 726

【数据分析】比较SparCC、Pearson和Spearman相关性估计方法在合成组学数据上的表现

【数据分析】比较SparCC、Pearson和Spearman相关性估计方法在合成组学数据上的表现

专注生信领域 659

深入解析网络编程:Socket基础与操作详解

这是因为在网络传输中,需要保证数据的一致性。因此,当数据在网络中传输时,必须按照大端序排列。为了确保数据在网络中正确传输,需要将主机字节顺序(Host Byte Order)转换为网络字节顺序。我们通常使用的有两种数据类型:短型(两个字节)和长型(四个字节)。

无敌岩雀的博客 3589

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【探索Linux】P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )

这篇文章详细介绍了常见的 Socket API,包括各种函数的用途和功能。首先列出了这些常见函数,并逐一进行了详细介绍。其中包括了socket()用于创建套接字、bind()用于绑定地址、listen()用于监听连接等基本函数,以及sendto()、recvfrom()等用于数据传输的函数。此外,还介绍了一些与套接字操作相关的函数,如setsockopt()、getsockopt()以及地址转换函数inet_pton()等。通过该文章,读者可以全面了解这些常见 Socket 函数的作用和用法。

Yawesh的博客 2898

温度PID控制PLC程序

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

socket网络编程接口常用函数

文章目录socket编程1.socket函数2.bind函数2.1 Sockaddr_in格式2.2 in_addr格式3. listen函数4.accept函数5.connect函数6.recv函数7.closesocket(),shutdown()函数 中断连接 socket编程 1.socket函数 int SOCKET socket(int af,int type,int protocol) af:位址资料族系 type:通讯方式 protocal:传输协定编号 返回值:-1表示建立socket

小小拓哥 563

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【Windows编程】Windows Socket API介绍

01、目录 目录01、目录02、浅谈Socket(套接字)03、浅谈TCP/IP七层模型04、浅谈三次握手,四次挥手05、Socket API介绍5.1 WSAStartup5.2 WSAClearup5.3 socket5.4 closesocket5.5 bind5.6 Listen5.7 accept5.8 connect5.9 send5.10 recv06、附录07、总结 02、浅谈Socket(套接字) socket(插座)编程是一门技术,它主要是在网络通信中经常用到。英文单词意思是“插座”。

Cain Xcy的博客 2773

C/C++ Linux Socket网络编程 TCP 与 UDP

详细介绍Linux环境C/C++如何使用socket通信,TCP与UDP;

cpp_learner的博客 1万+

SOCKET编程(3):相关结构体与函数

SOCKET编程(3):相关结构体与函数详解

Solititude的博客 1400

【计算机网络】什么是socket编程?以及相关接口详解

我们使用一张图片很形象的可以看出socket所处的位置。从上图看出,Socket处于应用层与传输层的中间软件抽象层,它是一组接口。并且前面我们也学过,运输层和网络层其实属于操作系统内层面,我们只给用户提供使用的接口即可,不可能让用户能直接访问到内核部分。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。linux下一切皆文件!!!所以本质来说Socket即是一种。

luhaoran814的博客 3332

linux网络编程常用函数详解与实例(socket-->bind-->listen-->accept)

常用的网络命令:netstat命令netstat是用来显示网络的连接,路由表和接口统计等网络的信息.netstat有许多的选项我们常用的选项是 -an 用来显示详细的网络状态.至于其它的选项我们可以使用帮助telnettelnet是一个用来远程控制的程序,但是我们完全可以用这个程序来调试我们的服务端程序的. 比如我们的服务器程序在监听8888端口,我们可以用telnet localhost 888

阳光岛主 1万+

Socket编程&用到的函数&TCP UDP实例

简单点说就是硬件厂商各有所好,并没有统一的约定制作制作哪一个,大端的优势在于第一个字节就是高位,很容易判断正负性。小端的优势在于第一个字节是低位,最后一个字节是高位,可以依次取出相应的字节进行运算,并且最终会把符号位刷新,这样运算起来更高效。大小端是针对非单字节数据的存取,比如short型,int型等。大端存储是将数据的高位存储在内存的低地址处,小端存储是将数据的低位存储在内存的低地址处。

weixin_47755728的博客 818

Python Socket编程详解

@author StormMa @date 2017-06-10 生命不息,奋斗不止! 今天,来总结一下Python中Socket编程的部分,首先申明一下Python的版本是3.5 开始之前 我想学习Socket之前,你应该去看看什么是Socket,Socket通信是怎么一个流程,我想只有了解这些之后,你才能更好地掌握Socket编程,这里我就引用一个图,来大致的说明一下Socket通

StormMaybin的博客 4198

Linux网络Socket实验,Linux下Socket编程实验资料摘录及手记

//--服务端--//-- bool create();intm_sock = -1;//domain:说明我们网络程序所在的主机采用的通讯协族(AF_UNIX和AF_INET等). AF_UNIX只能够用于单一的Unix系统进程间通信,而AF_INET是针对Internet的,因而可以允许在远程主机之间通信//type:我们网络程序所采用的通讯协议(SOCK_STREAM,SOCK_DGRAM等...

weixin_26806355的博客 296

linux shell 撤销 listen socket,linux网络编程常用函数详解与实例(socket-->bind-->listen-->accept)...

常用的网络命令:netstat命令netstat是用来显示网络的连接,路由表和接口统计等网络的信息.netstat有许多的选项我们常用的选项是 -an 用来显示详细的网络状态.至于其它的选项我们可以使用帮助telnettelnet是一个用来远程控制的程序,但是我们完全可以用这个程序来调试我们的服务端程序的. 比如我们的服务器程序在监听8888端口,我们可以用telnet localhost 888...

weixin_42307290的博客 371

网络socket编程(udp、tcp)

如此理解connect三个参数是容易了,我必需指定数据发送的地址,同时也必需指定数据从哪里发送,这正好是connect的前两个参数,而第三个参数是为第二个参数服务的。(inet_ntoa)addr:发送到哪,服务端的地址,connect是主动连接的一方,要存在一个被动连接的一方需要调用listen以接受connect的连接请求,被动连接的一方就是服务器。accept:当客户端的连接请求到达后,accept函数会创建一个新的套接字,并返回一个新的套接字描述符,该描述符与客户端的套接字建立连接。

qq_63641691的博客 1966
上一篇: 【socket编程-05】使用socket()函数创建套接字
下一篇: 【socket编程-07】使用listen()和accept()函数
魔方的块
博客等级 码龄11年 1056粉丝 119原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值