码迷,mamicode.com
首页 > 其他好文 > 详细

游戏网络编程(二)

时间:2017-04-02 13:24:30      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:队列   作用   通信   习惯   百度一下   资源   strong   缓冲区   val   

游戏网络编程(二)

本篇介绍Socket编程,因为我觉得每个开始接触网络编程的人应该都是先从了解socket编程开始的吧。后面介绍的WebSocket也会和Socket编程的概念做比较,因此先介绍下Socket编程。

什么是Socket

关于什么是Socket,我并不想做太复杂专业的介绍,毕竟百度一下,能找到很全面的说明。这里只做简单的介绍,Socket是一套API,也就是函数接口,用来进行网络协议通信和传输的。我们现在提的Socket基本上都是指最最最起源的伯克利发布的Socket。其他的诸如Winsock,CSocket,等等基本要么是衍生自伯克利Socket,或者遵循和伯克利Socket相同的标准的。
程序界发展到今天,大家不觉得其实所谓的标准已经非常多,非常混乱了么,呼唤大一统时代到来啊。扯远了,可能后面我会专门搞一篇对比不同的SocketAPI的介绍吧。

常用的Socket函数API

所以我们接触的基本的Socket函数,都是伯克利的Socket函数。

WinSock

是windows自行实现的一套socket,虽然不是同样的开发人员实现,也非源自于伯克利socket,但其实现后确有类似伯克利的标准。所以为什么要搞个winsock呢?大厂都喜欢玩标准,没玩出什么名堂,反而把我们玩的够呛,谁愿意没事去熟悉两套差不多的东西(又跑远了)。其实WinSock是一个C++的头文件,其中包含了windows定义的socket,所以也就把它定义的Socket称为WinSock

CSocket

CSocket也是微软定义的(真是想抽MS两嘴巴)。是在MFC中封装的一套socket,也就是说你使用mfc的库才会用到这套socket。但MFC,现在基本已经没人在用了吧。


Socket函数介绍

以下所有接口成功返回0,失败返回-1

socket

建立某种类型的套接字,并返回一个整数型来表示这个套接字(觉得理解不了的同学,理解为ID好了)。并分配系统资源给这个套接字(内存什么总要给人家的吧)。

这里要说明的是,因为伯克利套接字最早被实现在unix环境上实现,所以有的术语对于我们习惯windows的开发人员很难一下子转换过来。比如这个返回的整形值,被称为描述符。什么是描述符?因为socket的底层的建立,函数执行,其实是涉及到系统内核操作的。而在unix系统内核中,将这个内核对象以文件系统来实现描述(好吧,大概就是这么个意思,我也没用过unix)。所以就沿用了这样一个称呼,File Descriptor,简写FD,所以知道为什么那么多网络编程的代码都是FD_XXX的,其实写成socket会死啊?

socket接收三个参数

参数说明
domain 指定要创建的Socket的地址协议簇,所以其枚举可以看到都是AF_XXX(AddressFamily)
type 指定传输方式,一般我们就使用的是SOCK_STREAM(流方式,TCP),SOCK_DGRAM(UDP)
protocol 指定传输使用的协议,比如是TCP,还是UDP协议

bind

将一个socket和一个代表socket的地址的struct进行关联,通常用在服务器端。在socket可以接收到其他主机端的连接时,必须先调用这个函数

虽然这个函数一般用在服务器端,但也不是说客户端不能用。

参数说明
sockfd 代表要执行bind操作的socket的描述符(fd出现了!)
my_addr 指针,指向要bind的地址的sockaddr结构
addrlen 指定第二个参数的大小,socklen_t类型

listen

只用于服务器端,使一个已经绑定的Tcp socket进入监听状态。这个函数只能针对面向连接的socket起作用

参数说明
sockfd 代表要执行bind操作的socket的描述符(fd又出现了!)
backlog 整数值,代表同一时刻,可以在队列里等待处理的连接数量

accept

只用在服务器端,同意一个收到的尝试建立连接的请求,会被通知,并创建一个关联到远端地址的socket来建立TCP连接。并且将这个请求连接从listen的队列中移除。

参数说明
sockfd 代表要执行bind操作的socket的描述符
cliaddr 指针,指向代表客户端的sockaddr地址信息结构
addrlen 指针,指定第二个参数的大小,socklen_t类型

connect

只用在客户端,当调用这个函数后,将和描述符指定的远端主机建立一个直接连接。当使用面向连接的协议,比如在一个Tcp socket上执行,将尝试确立一条tcp连接(换句话说,可以在udp上使用,只是然并卵而已)。如果是使用在Udp上,该函数会指定使用send和recv函数发送和接收数据的远端地址,防止来自其他源的数据

send,sendto

这两个函数都是用来发送数据的,区别在于send一般用于Tcp,sendto用于Udp,因为sendto函数具有一个指向远端地址的数据结构的指针。

但从上面的解释看,send在某些情况下也可以用于udp发送,比如在一些不用指定远端地址的情况下,比如广播,这个需要做个实验

参数说明
s 指定一个要执行发送操作的socket
buf 指向你要发送的数据的指针
len 你要发送的数据长度
flags 允许你指定数据如何发送的更多的信息。如果你需要用一般的方式发送数据,将该参数设置为0
to 指向要发送的远端地址(sendto使用)
tolen 代表to指针指向的结构的大小

recv,recvfrom

一旦你建立以一个socket连接,你可以使用这两个函数从远端接收数据。不同的在于recvfrom指定了一个指向远端地址的结构指针,来指定从什么地方接受数据。一般来说recv用于Tcp,recvfrom用于Udp

参数说明
s 指定一个要执行发送的socket
buf 指向你要接收数据缓冲区的指针
len 指定缓冲区的大小
flags 控制如何接收数据,如果只是以通常方式接收数据的话使用0
from 指向一个代表远端地址的结构,告诉你数据从哪里来
fromlen 代表from指针指向的地址结构的大小

select

用来挂起,并等待提供的socket列表准备好读(接收),写(发送)数据,或是发生一个错误。我们使用一系列宏来构建一个socket的集合,并将其传递给select函数

参数说明
n 这个值要比后面三个socket结合中最大的描述符(id)还要大1
readfds 指向你需要知道哪些socket处于可接收数据状态的socket的集合
writefds 指向你需要知道哪些socket处于可发送数据状态的的集合
exceptfds 指向哪些socket发生错误的socket集合

当select成功返回后,需要遍历这些集合,确定socket是否在该集合中,然后进行对其进行操作。

setsocketopt,getsocketopt

用来对socket进行一些相关的设置

参数说明
s 指向要设置的socket
level 这个参数要设置成SOL_SOCKET
optname 你要设置的选项的名称
optval 选项值
optlen 指向你optval代表的值的长度

poll

这个函数和select函数非常相似,都是用来监视哪些socket已经获得事件,处于可以recv,或是send的状态,不同的是,select每次要传递时可能需要重新构造一个socket集合(读写的集合有了变化),而poll使用的集合,其每个集合元素,除了包含socket还包含有相应的事件状态,因此其不用每次都构造集合(无视集合中元素的变化),只需要改变集合元素中事件状态值就可以了,因此更高效

参数说明
ufds 一个pollfds结构的集合
nfds ufds数组的数量
timeout 超时时间,负数代表一致等待。如果在指定时间内没有事件发生,poll会返回

其他函数日后有机会专门搞一篇详细的介绍吧

游戏网络编程(二)

标签:队列   作用   通信   习惯   百度一下   资源   strong   缓冲区   val   

原文地址:http://www.cnblogs.com/indie-developer/p/6658714.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!