1.什么是SOCKET (SOCKET也就是所谓的套接字)
简单的说它是一个文件.它是使用标准Unix文件描述符和其它程序通讯的方式,Unix中的一切就是文件,程序在执行任何形式的 I/O 的时候,程序是在读或者写一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数,这个文件可能是一个网络连接,FIFO,管道,终端,磁盘上的文件或者什么其它的东西.
这里的SOCKET就是一个特定的文件描术符,(称之为Internet 套接字)用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过它向网络发出请求或者应答网络请求.
Internet 套接字分为多种形式,常见的有stream sockets流格式和datagram sockets数据报格式.等.但经常用的就是这两种.数据报套接节有时候也叫无连接套接字.
流式套接字.
流格式的套接字就是有连接的套接字.它是可以双向通讯的数据流.如果你向流格式的套接字按顺序输出"1,2",那么它们将按顺序"1,2"到达另一边.
比如常见的telnet程序就是使用的流式套接字.还有WWW浏览器使用的 HTTP协议也使用它们来下载页面,实际上,当你通过端口80 telnet 到一个 WWW 站点,然后输入 "GET pagename" 的时候,你也可以得到HTML页面的内容
流式套接字使用了一种叫做"TCP"的协议来控制你的数据按顺序到达并不会有错.
我们常说的"TCP/IP"其实是两个东西,它表示"TCP协议"和"Internet 协议"
Internet 协议只是处理Internet 路由而已"
数据报套接字.
数据报套接字也叫无连接套节字.假设你发送一个数据报,它可能会到达,它也可能次数颠倒了.如果它到达,那么在这个包的内部是无错误的.对于数据报套接字,你只需要建立一个包.并构造一个有目标信息的IP头.然后把这个包发送出去.所以说它是无连接的.
数据报套接字使用的是用户数据协议也叫做"UDP"协议来按据数据的传输.当然它们也是用"Internet 协议"来处理Internet 路由的.
使用数据报套接字的程序有tftp, bootp等等.当然在这里你也许会问"如果数据包在传送过程中丢失,程序将如何正常工作?" 每个程序在UDP上有自己的协议.协议每发出一个数据包,收到者必须发回一个包来告诉发送者"我收到了".如果一定时间内发送者没有收到应答,它将重新发送.直到收到应答为止.
2.关于网络分层模型.
首先谈谈数据是如何在网络中以包的方式来传送的.假设现有一台机器上的TFTP程序和另一台机器上的程序通讯.我们知道TFTP程序是使用数据报套接字的.原始数据最先是被第一层协议(这里也就是TFTP)在它的报头包装好,然后整个数据(包括TFTP头)被另一层协议(在这里就是UDP)包装.然后再下一个(IP协议)包装这样一直下去直到物理硬件层(比如以太网卡)当另外一台机器收到数据包.硬件层先剥去以太网头,内核剥去IP和UDP头,最后由TFTP程序剥去TFTP头.就得到了原始数据.
这一过程对应一个网络分层模型.这种模型在描述网络系统上相对于其它模型有很多优点.例如:你可以写一个套接字程序而不用关心数据的物理传输.因为底层的程序会为你处理它们.
网络分层模型:
应用层 (Application)
表示层 (Presentation)
会话层 (Session)
传输层(Transport)
网络层(Network)
数据链路层(Data Link)
物理层(Physical)
如果把它对应到 Unix,结果是:
应用层(Application Layer) (telnet, ftp,等等)
传输层(Host-to-Host Transport Layer) (TCP, UDP)
Internet层(Internet Layer) (IP和路由)
网络访问层 (Network Access Layer) (网络层,数据链路层和物理层)
看了上面的内容就知道建立一个简单的数据包其实是一个非常复杂的工作.但是对于用户而言我们只需要简单的调用send()或sendto()就可以了.内核将为你建立传输层和Internet层,硬件完成网络访问层.
3.SOCKET编程中几个重要的数据结构.
首先是sockaddr它的定义:
struct sockaddr
{
unsigned short sa_family;
char sa_data[14];
};
sa_family 能够是各种各样的类型,但是在这篇文章中都是 "AF_INET".
sa_data包含套接字中的目标地址和端口信息.
为了处理sockaddr程序员创造一个并列的结构sockaddr_in后面的in表示"Internet"它的定义如下:
struct sockaddr_in
{
short int sin_family;
unsigned short int sin_port; /* 端口 */
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
用sockaddr_in结构可以轻松的处理套接字地址的基本元素.注意:sin_zero的作用是为了与结构体sockaddr保持相同的长度.在使用的时候应用memset()类型的函数来将它全部置0.正是有了它.你才可以在使用sockaddr的地方仍然使用sockaddr_in结构代替.只需要做简单的转换即可.
同时注意sockaddr_in中的sin_family和sockaddr中的sa_family一致.
最后sin_port和sin_addr必须是网络字节顺序 (Network Byte Order)
4.关于字节顺序.
事实上有两种字节排列顺序:A.重要的字节在前.B.不重要的字节在前面.
而前一种字节排列顺序就叫网络字节顺序.
当我们说某一数据必须按照网络字节顺序.那么你就需要调用函数(例如:htons())来将它从本机字节顺序转换成网络字节顺序.我们能够转换两种类型"short"和"long"对于unsigned也实用
假如:你想将short从本机字节顺序转换成网络字节顺序.用"h"表示本机(host),接着是"to"然后用"n"表示网络(network)最后用"s"表示short类型,这样就可以得到这个函数htons()...该类型的函数有:
htonl()
ntohs()
ntohl()
记住:这里是Unix的世界.在你将数据放到网络上的时候,请确信它们是按网络字节顺序排列的.
为什么在sockaddr_in结构中sin_addr和sin_port需要转换成网络字节顺序.而sin_family不需要呢?
答案是:sin_addr和sin_port分别封装在包的IP层和UDP层.因此它必须按网络字节顺序.但是sin_family只是被内核用来判断数据结构中包含什么类型的地址.它并没有被放到网络上进行传送.所以它可以是本机字节顺序.
5.IP地址及其处理方法
假设你现在已经创建了一个sockaddr_in结构体myaddr 现在你要将IP地址"192.168.1.110"存贮到结构体中.你只需要调用函数inet_addr()将IP地址从点数格式转换成无符号长整型.例:
myaddr.sin_addr.s_addr = inet_addr("192.168.1.110");
需要注意的是:函数inet_addr()返回的已经是网络字节顺序.所以你无需再调用htonl()函数来进行转换.
还需要注意一点:函数inet_addr()在错误时返回值为-1.刚好等于IP地址"255.255.255.255"这可是个广播地址.所以在使用inet_addr()函数时一定要进行错误检查.
函数inet_ntoa()则刚好相反,它可以将一个结构体in_addr输出成点数格式的IP地址.
注意:inet_ntoa()函数将结构体in_addr作为一个参数.而不是长整型.
6.socket()函数
功能:建立一个套接字
定义:int socket(int domain, int type, int protocol);
参数domain指定通信发生的区域,windows中只支持"AF_INET"
参数type描述要建立的套接字的类型.如SOCK_STREAM类型或SOCK_DGRAM类型
参数protocol说明该套接字使用的特定协议.如果调用者不希望特别指定使用的协议,则置为0,使用默认的连接模式
函数socket()将会根据指定的三个参数建立一个套接字.并将相应的资源分配给它.同时返回一个整型套接字描述符.
注意:如果该函数调用失败返回值为-1.
7.bind()函数
功能:将套节字和本地地址关联在一起
定义:int bind(SOCKET s,struct sockaddr *name, int namelen);
参数s是由socket()函数返回的并且未作连接的套接字描述符
参数name是赋给套接字s的本地地址结构的指针.(也就是sockaddr_in结构)
参数namelen表明了本地地址结构的长度.
函数调用成功返回0,有错误则返回-1.
在进行绑定本地地址时有几个注意事项:
A.将sockaddr_in结构的sin_port置为0时,告诉系统随机选择一个没有使用的端口.
B.将sockaddr_in结构的sin_addr.saddr置为INADDR_ANY,告诉它自动填上它所运行的机器的IP地址
C.如果需要手动指定端口.一定记住不要采用小于1024的端口,因为所有小于1024的端口都被系统保留.而我们可以选择的端口则从1024到65535
D.如果你使用connect()来和远程机器通讯,你不需要关心你的本地端口,你只需要简单的调用connect()就可以了,它会检查套接字是否绑字端口,如果没有,它会自己绑定一个没有使用的端口.
8.connect()函数
定义:int connect(SOCKET s,struct sockaddr *name, int namelen);
参数s是欲建立连接的本地套接字描述符.
参数name是将要连接的目标地址结构sockaddr的指针.
参数namelen指明目标地址结构的长度
函数在错误时返回-1.
注意:在使用connect()函数来和远程机器建立连接时可以不需要调用bind()函数,因为我在乎本地端口号.我只关心我要连接到哪里(也就是目标),并且连接后目标会自动获取我们的IP地址,以及我们所使用的端口等信息.
9.listen()和accept()函数.
假如你不希望与远程的一个地址相连,那么你就需要等待接入请求.并且用各种方法处理它们.这个过程就是听及listen()然后接受accept()
listen()用于监听连接.它地调用需在accept()之前
定义:int listen(SOCKET s, int backlog);
参数s标识一个本地已建立,尚未连接的套接字描述符.
参数backlog表示请求连接队列的最大长度,大多数系统允许最大数目是20.
成功返回0,错误则返回-1.
accept()函数
系统调用accept()的情况就像有一台远程的机器通过你在监听listen()的端口连接connect()到你的机器.这个连接将被加入到等待接受的队列中.然后你调用accept()告诉它你有空闲的连接.这时系统将返回一个新的套接字描术符.这样你就有两个套接字了.原来的一个还在监听那个端口是否有新的连接到来.新的这个套接字则准备发送send()或者接收recv()数据了.
定义:SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen);
参数s为本地套接字描述符,也就是正在用于监听listen()的那个套接字描术符.
参数addr是一个struct sockaddr结构指针.它用来存贮客户的地址.也就是要求连接的机器的地址信息.
参数addrlen保存客户方套接字地址的长度(注意它是一个int型指针)
函数调用成功将会返回一个套接字(表示接收到的套接字).如果失败则返回-1.
10.send()和recv()函数
不管是服务端程序或是客户端程序都将使用这两个函数从TCP连接的另一端发送或接收数据.
send()函数
定义:int send(int s, void *msg, int len, int flags);
参数s是你相发送数据的套接字描述符.这里可能是socket()返回的,也可能是accept()返回的.
参数msg是你想要发送的数据的指针.
参数len是将要发送的数据的长度.
参数flags通常设为0.
如果将要发送的数据的长度len大于套接字s的发送缓冲区的长度.该函数将返回-1.
如果len小于或等于s的发送缓冲区长度,那么send()先检果协议是否正在发送s的发送缓冲区中的数据.如果是就等待协议把数据发送完.如果协议还没有开始发送s的发送缓冲区中的数据或者s的发送缓冲区中没有数据,那么send()就比较发送缓冲区和剩余空间和len,如果len大于s的发送缓冲区剩余空间send()就会一直等待协议把s的发送缓冲区中的数据发送完.如果len小于发送缓冲区的剩余空间send()就把msg所指的数据拷贝到s的发送缓冲区剩余空间里.
注意:并不是send()把数据传送到连接的另一端.而是具体的协议来完成传送的.send()只是把数据拷贝到套接字的发送缓冲区剩余空间里而以.
如果send()拷贝数据成功.就返回实际拷贝数据的字节数.
另外send()把数据拷贝到套接字的发送缓冲区中就返回了.此时.这些数据并不一定马上被传送到连接的另一端.
注意:在Unix系统下.如果send()在等待协议传送数据时网络断开的话,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止.
recv()函数
定义:int recv(int s, void *buf, int len, int flags);
参数s为接收端的套接字描述符.
参数buf指明一个缓冲区.该缓冲区用来存放recv()接收到的数据.
参数len指明缓冲区的长度.
参数flags通常设为0.
成功将返回实际写入缓冲区的数据的长度.失败返回-1.
同样的.recv()函数只是负责把数据从s的接收缓冲区中拷贝到buf缓冲区中.真正的接收数据的工作是由协议来完成的.所以协议接收到的数据有可能大于buf缓冲区的长度.在这种情况下要调用多次recv()函数才能把接收缓冲区中的数据拷贝完.
另外:除了send()函数外其它的socket函数比如recv()都要先等待套接字的发送缓冲中的数据被协议传送完毕才能执行.
今天就到此吧!!!
相关推荐
网课、网页视频倍速播放简单脚本
一个简单的网页视频倍速脚本
socket、listen、connect、bind、accept函数详解
socket函数 为了执行网络I/O,一个进程必须做的第一件事情就是调用socket函数,指定期望的通信协议 #include<sys/socket.h> int socket(int family,int type,int protocol) 返回成功则返回非负文件描述符,若出错则为-1 其中family参数指明协议族,它是某些常量AF_INET:IPv4、AF_INET:Ipv6等...
手把手教你用LTspice仿真扬声器阻抗曲线(附Dayton/Focal型号库)
本文详细介绍了如何使用LTspice仿真软件构建高精度扬声器模型,包括获取Dayton/Focal等厂商的SPICE模型库、模型导入方法、阻抗测试电路搭建及仿真设置。通过手把手教学,帮助读者快速掌握扬声器阻抗曲线的仿真技术,提升音响系统设计效率。
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
【数据清洗】数据清洗流程及经验
预处理阶段 预处理阶段主要做两件事情: 一是将数据导入处理工具。 二是看数据。包含两个部分:一是看元数据,包括字段解释、数据来源、代码表等等一切描述数据的信息;二是抽取一部分数据,对数据本身有一个直观的了解,并且初步发现一些问题,为之后的处理做准备。 第一步:缺失值清洗 四个步骤: 1、确定缺失值范围:对每个字段都计算其缺失值比例,然后按照缺失比例和字段重要性,分别制定策略。 2、去除不需要的...
【02】【VisionMaster V4.0.0 】安装教程—— 授权文件更新报错:应用程序与本地LM通讯出错(怀疑电脑加密 和 上网受限 造成的 )
本文详细介绍了海康VisionMaster 4.0试用版的安装流程及常见问题解决方案。主要内容包括:1)从官网下载基础安装包、试用补丁和授权文件;2)按顺序安装主程序、补丁和授权文件;3)针对授权失败问题提供两种解决方案(更换未加密电脑或使用加密狗);4)说明试用版的功能限制(30天试用期、2个流程限制等)。文章特别指出电脑加密可能导致授权失败,并提供了安装报错时的处理建议,为初次使用者提供了完整的安装指导。
Socket网络编程
Socket网络编程是指利用网络套接字(socket)实现客户端和服务端之间的通信。在此过程中,应用程序使用各种协议(如TCP/IP协议)在网络上通信。Socket网络编程开发步骤
保姆级教程:用CellOracle 0.10.13从单细胞数据构建基因调控网络(附完整代码)
本文提供了一份详细的CellOracle 0.10.13使用指南,帮助用户从单细胞数据构建基因调控网络。通过Python接口,即使是生物信息学新手也能快速掌握数据准备、KNN插补、GRN计算及可视化等关键步骤。文章包含完整代码和实用技巧,助力单细胞转录组数据分析。
Socket网络编程:TCP与UDP
socket网络编程:TCP与UDP
Arduino创意作品实战案例:手把手教你做温控风扇
通过这个实用的arduino创意作品,轻松实现温度感应与风扇自动控制,结合传感器与编程逻辑,打造智能散热系统,是入门者理想的arduino创意作品实践项目。
OpenWrt虚拟机磁盘扩容实战:从SquashFS到ext4的完整避坑指南
本文详细介绍了OpenWrt虚拟机磁盘扩容的完整流程,重点对比了SquashFS和ext4文件系统在扩容操作上的关键差异。通过五步安全迁移法和直接分区调整方案,帮助用户有效解决磁盘空间不足问题,同时提供高级技巧和故障排除指南,确保扩容过程顺利无坑。
Socket网络编程学习笔记
Socket网络编程学习笔记 一、IP地址操作类 1、IPAddress类 a、在该类中有一个 Parse()方法,可以把点分的十进制IP表示转化成IPAddress类,方法如下: IPAddress address = IPAddress.Parse(“192.168.0.1”); b、IPAddress提供4个只读字段
第十四节《OpenCascade集成Qt》
将 OpenCascade 与 Qt 集成是开发图形界面应用的常见需求。通过将 OpenCascade 的几何建模与 Qt 的图形用户界面(GUI)功能结合,可以创建强大而灵活的 CAD 或建模工具。OpenCascade 提供了与 Qt 的集成接口,允许你在 Qt 应用程序中嵌入 OpenCascade 的视图,执行几何操作,并与用户进行交互。以下是 OpenCascade 与 Qt 集成的详细步骤:首先,确保已安装 OpenCascade 和 Qt。你可以从 OpenCascade 官方网站或通过包管理
SOCKET网络编程学习笔记
SOCKET网络编程学习笔记
efm32 入门.pdf
本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。
精雕软件(JDpaint) 5.5 绿色版
精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版
java学习笔记————Socket网络编程小总结
**对于网络编程其实就相当于,在生活中人与人之间的交流,提问的一方作为用户端,回答问题的一方作为服务器端** 接下来我就和大家我学习socket网络编程所学到的知识
复分析 阿尔福斯(Ahlfors) 第三版答案 英文
答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案
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)
VC中sqlite的使用
在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示
网络编程学习笔记一:Socket编程
“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型有哪些?还有
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架构是一种比较早的软件架构,主要用
python学习笔记2:socket网络编程
如何使用socket进行网络编程
Linux Socket 网络编程学习笔记
Linux Socket 网络编程学习笔记
【学习笔记】简单的socket网络编程实例
TCP的三次握手(图片来自百度百科) TCP的四次分手(图片来自百度百科) 单向交互套结字 服务端 /* * Author: xusongqi@live.com * * Created Time: 2014年03月19日 星期三 17时29分14秒 * * FileName: sock_server.c * * Descript
【Java学习笔记】基于Socket的TCP网络编程和UDP网络编程
一、基于Socket的TCP网络编程 TCP协议的特点: 使用TCP协议前,须先建立TCP连接,形成传输数据通道 传输前,采用“三次握手” 方式,点对点通信, 是可靠的 TCP协议进行通信的两个应用进程:客户端、 服务端。 在连接中可进行大数据量的传输 传输完毕,需释放已建立的连接, 效率低 客户端Socket 客户端程序的工作过程包含以下四个基本的步骤: 创建 Socket: 根据指定服务...
Windows Socket网络编程学习笔记一
作者:朱金灿 来源:blog.youkuaiyun.com/clever101 如何理解Windows Socket? 我的理解:Windows Socket相当于Windows平台上两个网络实体开辟的一条通信通道,这条通信通道的实现细节对网络双方是不可见的(呵呵,你就知道它是Windows制造)。通过这条通道,网络双方可以传输各种数据。 你可能...
网络编程学习笔记:Socket编程
一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型有哪些?还有s...
1万+



被折叠的 条评论
为什么被折叠?



