Windows下的网络编程——1、初识Socket(TCP)
WinSocket
一、
什么是Socket?
二、
根据底层协议Socket开发接口提供面向连接和无连接两种服务方式
允许小的丢包就用第二种方式,对应UDP协议
三、
四、IP地址的表现形式
1、网络传送中,IP地址被保存为32位,低位地址存储高位字节
2、不同主机对IP地址的存储使用的格式可能不一样,为此,我们需要明白主机与网络字节
的相互转化
五、socket编程所用到的一些函数或结构体
1、WSAStartup
wsastartup()函数向操作系统说明,我们要用哪个库文件。 因此就可以将库文件与当前的
应用程序绑定,从而就可以调用该版本的socket的各种函数了。 一句话解释:wsastartup()
主要就是进行相应的socket库绑定。
2、WSACleanup
应用程序在完成对请求的Socket库的使用后,要调用WSACleanup函数来解除与Socket
库的绑定并且释放Socket库所占用的系统资源。
3、int socket(int domain,int type, int protocol)
这个函数建立一个协议族为domain、协议类型为type、协议编号为protocol的套接字文件描述符(socket)
family指明了协议族/域,通常AF_INET、AF_INET6、AF_LOCAL等;
type是套接口类型,主要SOCK_STREAM、SOCK_DGRAM、SOCK_RAW;
protocol一般取为0。成功时,返回一个小的非负整数值,与文件描述符类似。
4、bind函数
int bind ( int sockfd, struct sockaddr * addr, socklen_t addrlen )
返回: 0 ──成功, - 1 ──失败
参数sockfd
指定地址与哪个套接字绑定,这是一个由之前的socket函数调用返回的套接字。调用bind的函数之后,该套接字与一个相应的地址关联,发送到这个地址的数据可以通过这个套接字来读取与使用。
参数addr
指定地址。这是一个地址结构,并且是一个已经经过填写的有效的地址结构。调用bind之后这个地址与参数sockfd指定的套接字关联,从而实现上面所说的效果。
参数addrlen
正如大多数socket接口一样,内核不关心地址结构,当它复制或传递地址给驱动的时候,它依据这个值来确定需要复制多少数据。这已经成为socket接口中最常见的参数之一了。
功能:
在套接口中,一个套接字只是用户程序与内核交互信息的枢纽,它自身没有太多的信息,也没有网络协议地址和 端口号等信息,在进行网络通信的时候,必须把一个套接字与一个地址相关联,这个过程就是地址绑定的过程。许多时候内核会我们自动绑定一个地址,然而有时用 户可能需要自己来完成这个绑定的过程,以满足实际应用的需要,最典型的情况是一个服务器进程需要绑定一个众所周知的地址或端口以等待客户来连接。这个事由 bind的函数完成。
5、sockaddr_in
地址结构
6、AF_INET
Vc上的定义是这样的
#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
7、listen函数:
int listen ( int sockfd, int backlog )
返回: 0──成功, - 1──失败
功能:
listen函数使用主动连接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。
第二个参数是同时处理的最大连接数
8、accept函数
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
(1)、功能
accept()系统调用主要用在基于连接的套接字类型,比如SOCK_STREAM和SOCK_SEQPACKET。它提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符。新建立的套接字不在监听状态,原来所监听的套接字也不受该系统调用的影响。
(2)、参数说明:
sockfd是由socket函数返回的套接字描述符,参数addr和addrlen用来返回已连接的对端进程(客户端)的协议地址。如果我们对客户端的协议地址不感兴趣,可以把arrd和addrlen均置为空指针
参数:
sockfd, 利用系统调用socket()建立的套接字描述符,通过bind()绑定到一个本地地址(一般为服务器的套接字),并且通过listen()一直在监听连接;
addr, 指向struct sockaddr的指针,该结构用通讯层服务器对等套接字的地址(一般为客户端地址)填写,返回地址addr的确切格式由套接字的地址类别(比如TCP或UDP)决定;若addr为NULL,没有有效地址填写,这种情况下,addrlen也不使用,应该置为NULL;
备注:addr是个指向局部数据结构sockaddr_in的指针,这就是要求接入的信息本地的套接字(地址和指针)。
addrlen, 一个值结果参数,调用函数必须初始化为包含addr所指向结构大小的数值,函数返回时包含对等地址(一般为服务器地址)的实际数值;
备注:addrlen是个局部整形变量,设置为sizeof(struct
sockaddr_in)。
如果队列中没有等待的连接,套接字也没有被标记为Non-blocking,accept()会阻塞调用函数直到连接出现;如果套接字被标记为Non-blocking,队列中也没有等待的连接,accept()返回错误EAGAIN或EWOULDBLOCK。
备注:一般来说,实现时accept()为阻塞函数,当监听socket调用accept()时,它先到自己的receive_buf中查看是否有连接数据包;
若有,把数据拷贝出来,删掉接收到的数据包,创建新的socket与客户发来的地址建立连接;
若没有,就阻塞等待;
(3)、返回值
成功时,返回非负整数,该整数是接收到套接字的描述符;出错时,返回-1,相应地设定全局变量errno。
9、recv函数
int recv( SOCKET s, char FAR *buf, int len, int flags);
第一个参数指定接收端套接字描述符;
第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
第三个参数指明buf的长度;
第四个参数一般置0。
10、send函数
与recv函数格式极其相似
11、connect函数(客户端)
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
参数:
sockfd:标识一个套接字。
serv_addr:套接字s想要连接的主机地址和端口号。
addrlen:name缓冲区的长度。
六、
1、
可以看到图中第二行8888端口经过转化后变成了47138…
所以说这个转化还是很有必要的
七、服务端代码:
八、 客户端代码
九、代码实验
1、我根据教程写了服务端,自己去写了客户端
我以虚拟机下的winxp作为服务端,以物理机为客户端,向同一局域网下的winxp发送信息
2、服务端
客户端:
我猜测,类似飞鸽或飞秋的局域网通信技术可能类似于这种方法
__EOF__

本文链接:https://www.cnblogs.com/lordtianqiyi/articles/15731984.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现