socket通信简介

socket通信简介

2023年7月15日发(作者:)

socket通信简介游戏⼀般是基于强联⽹的,服务端与客户端时时都在进⾏信息的交互,故多采⽤socket进⾏服务端与客户端的通信,今天我们了解⼀下C#的socket知识。1、什么是Socketsocket 实际上是⽹络通信端点的⼀种抽象,它提供了⼀种发送和接收数据的机制。⽹络通信,归根结底是⽹络端点间的通信,通过socket,⽤户所开发的应⽤程序可以通过⽹络与其他socket应⽤程序通信。从技术观点看,也可以将socket通信理解为⽹络进程间的通信,⽹络地址只能确定⼀台计算机,还不能确定通信进程,socket中还需要确定端⼝号。在⼀台计算机中,⼀个端⼝⼀次只能分配给⼀个进程,即在⼀台计算机中,端⼝号与进程之间是⼀⼀对应的关系,因此,通过⽹络地址和端⼝号就可以唯⼀确定整个Internet中的⼀个通信原理,也就是可以近似理解为:

套接字(socket)=⽹络地址(ip)+端⼝号(port)2. 进程与线程的区别进程是⼀个具有独⽴功能的程序关于某个数据集合的⼀次运⾏活动。它可以申请和拥有系统资源,是⼀个动态的概念,是⼀个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表⽰。通常在⼀个进程中可以包含若⼲个线程,它们可以利⽤进程所拥有的资源。在引⼊线程的操作系统中,通常都是把进程作为分配资源的基本单位,⽽把线程作为独⽴运⾏和独⽴调度的基本单位。由于线程⽐进程更⼩,基本上不拥有系统资源,故对它的调度所付出的开销就会⼩得多,能更⾼效的提⾼系统内多个程序间并发执⾏的程度。线程和进程的区别在于,⼦进程和⽗进程有不同的代码和数据空间,⽽多个线程则共享数据空间,每个线程有⾃⼰的执⾏堆栈和程序计数器为其执⾏上下⽂。多线程主要是为了节约CPU时间,发挥利⽤,根据具体情况⽽定。线程的运⾏中需要使⽤计算机的内存资源和CPU。3、C#中 socket的基本操作既然socket是“open—write/read—close”模式的⼀种实现,那么socket就提供了这些操作对应的函数接⼝。下⾯以TCP为例,介绍⼏个基本的socket接⼝函数。3.1、socket()函数 public Socket(AddressFamily family, SocketType type, ProtocolType protocol);socket函数对应于普通⽂件的打开操作。普通⽂件的打开操作返回⼀个⽂件描述字,⽽socket()⽤于创建⼀个socket描述符(socketdescriptor),它唯⼀标识⼀个socket。这个socket描述字跟⽂件描述字⼀样,后续的操作都有⽤到它,把它作为参数,通过它来进⾏⼀些读写操作。正如可以给fopen的传⼊不同参数值,以打开不同的⽂件。创建socket的时候,也可以指定不同的参数创建不同的socket描述符,socket函数的三个参数分别为:family:即协议域,⼜称为协议族(family)。常⽤的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采⽤对应的地址,如AF_INET决定了要⽤ipv4地址(32位的)与端⼝号(16位的)的组合、AF_UNIX决定了要⽤⼀个绝对路径名作为地址。type:指定socket类型。常⽤的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的类型有哪些?)。protocol:故名思意,就是指定协议。常⽤的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议(这个协议我将会单独开篇讨论!)。

注意:并不是上⾯的type和protocol可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会⾃动选择type类型对应的默认协议。当我们调⽤socket创建⼀个socket时,返回的socket描述字它存在于协议族(address family,AF_XXX)空间中,但没有⼀个具体的地址。如果想要给它赋值⼀个地址,就必须调⽤bind()函数,否则就当调⽤connect()、listen()时系统会⾃动随机分配⼀个端⼝。3.2、bind()函数正如上⾯所说bind()函数把⼀个地址族中的特定地址赋给socket。 public void Bind(EndPoint localEP);使 与⼀个本地终结点相关联。

函数的参数为终结点 EndPoint ,终结点是⽤来保存IP和端⼝号

终结点的实例化⽅法为:EndPoint point = new IPEndPoint(("192.168.1.26"), 6000);3.3、listen()、connect()函数如果作为⼀个服务器,在调⽤socket()、bind()之后就会调⽤listen()来监听这个socket,如果客户端这时调⽤connect()发出连接请求,服务器端就会接收到这个请求。public void Listen(int backlog);// 摘要: // 将 置于侦听状态。 // // 参数: // backlog: // 挂起连接队列的最⼤长度。 // // 异常: // Exception: // 试图访问套接字时发⽣错误。 有关更多信息,请参见备注部分。 // // DisposedException: // 已关闭。客户端连接public void Connect(EndPoint remoteEP); // 摘要: // 建⽴与远程主机的连接。 // // 参数: // remoteEP: // nt,表⽰远程设备。 // // 异常: // ntNullException: // remoteEP 为 null。 // // Exception: // 试图访问套接字时发⽣错误。 有关更多信息,请参见备注部分。 // // DisposedException: // 已关闭。 // // tyException: // 调⽤堆栈上部的调⽤⽅⽆权执⾏所请求的操作。 // // dOperationException: // 为 (32)。listen函数将socket变为被动类型的,等待客户的连接请求。客户端通过调⽤connect函数来建⽴与TCP服务器的连接。3.4、accept()函数TCP服务器端依次实例化socket、bind()、listen()之后,就会监听指定的socket地址了。TCP客户端依次调⽤实例化客户端socket、connect()之后就想TCP服务器发送了⼀个连接请求。TCP服务器监听到这个请求之后,就会调⽤accept()函数取接收请求,这样连接就建⽴好了。之后就可以开始⽹络I/O操作了,即类同于普通⽂件的读写I/O操作。public Socket Accept();// 摘要: // 为新建连接创建新的 。 // // 返回结果: // 新建连接的 。 // // 异常: // Exception: // 试图访问套接字时发⽣错误。 有关更多信息,请参见备注部分。 // // DisposedException: // 已关闭。 // // dOperationException: // 正在接受的套接字不会侦听连接。 在调⽤ () 之前必须调⽤ (nt) // 和 (32)。如果accpet成功,那么其返回值是由内核⾃动⽣成的⼀个全新的socket,代表与返回客户的TCP连接。注意:accept的第⼀个参数为服务器的socket描述字,是服务器开始调⽤socket()函数⽣成的,称为监听socket描述字;⽽accept函数返回的是已连接的socket描述字。⼀个服务器通常通常仅仅只创建⼀个监听socket描述字,它在该服务器的⽣命周期内⼀直存在。内核为每个由服务器进程接受的客户连接创建了⼀个已连接socket描述字,当服务器完成了对某个客户的服务,相应的已连接socket描述字就被关闭。4、TCP的三次握⼿建⽴连接详解我们知道tcp建⽴连接要进⾏“三次握⼿”,即交换三个分组。⼤致流程如下:在TCP/IP协议中,TCP协议提供可靠的连接服务,采⽤三次握⼿建⽴⼀个连接。

第⼀次握⼿:建⽴连接时,客户端发送syn包(syn=j)到服务器,并进⼊SYN_SEND状态,等待服务器确认;

第⼆次握⼿:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时⾃⼰也发送⼀个SYN包(syn=k),即SYN+ACK包,此时服务器进⼊SYN_RECV状态;

第三次握⼿:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进⼊ESTABLISHED状态,完成三次握⼿。 完成三次握⼿,客户端与服务器开始传送数据.

总结:客户端的connect在三次握⼿的第⼆个次返回,⽽服务器端的accept在三次握⼿的第三次返回。

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1689408576a243306.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信