游戏网络编程(二)

游戏网络编程(二)

本篇介绍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会返回

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

时间: 2024-12-28 20:54:56

游戏网络编程(二)的相关文章

Linux网络编程(二)

服务套和客户机的信息函数 1.字节转换函数 在网络上面有着许多类型的机器,这些机器在表示数据的字节顺序是不同的, 比如i386芯片是低字节在内存地址的低端,高字节在高端,而alpha芯片却相反. 为了统一起来,在Linux下面,有专门的字节转换函数. unsigned long int htonl(unsigned long int hostlong)     unsigned short int htons(unisgned short int hostshort)     unsigned

winform网络编程(二)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

安卓第八天笔记--网络编程二

安卓第八天笔记--网络编程二 1.网络图片查看器 /** * 网络图片查看器 * 1.获取输入的URL地址,判断是否为空 * 2.建立子线程,获取URl对象new URL(path) * 3.打开连接获取HttpURLConnection conn = (HttpURLConnection) url.openConnection(); * 4.设置连接超时时间conn.setConnectionTimeOut(5000)毫秒 * 5.设置请求方式setRequestMethod * GET或者P

网络编程(二)

网络编程(二)    >>>思维导图>>>中二青年 基于TCP协议的Socket套接字 server端 import socket sk = socket.socket() sk.bind(('127.0.0.1',8898)) # 把地址绑定到套接字 sk.listen() # 监听链接 conn,addr = sk.accept() # 接受客户端链接 ret = conn.recv(1024) # 接收客户端信息 print(ret) # 打印客户端信息 conn

C#网络编程二:Socket编程

一:什么是SOCKET socket的英文原义是"孔"或"插座".作为进程通信机制,取后一种意思.通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄(其实就是两个程序通信用的).socket非常类似于电话插座.以一个电话网为例:电话的通话双方相当于相互通信的2个程序,电话号码就是ip地址.任何用户在通话之前,首先要占有一部电话机,相当于申请一个socket:同时要知道对方的号码,相当于对方有一个固定的socket.然后向对方拨号呼叫

游戏网络编程(三)——WebSocket入门及实现自己的WebSocket协议

(一)WebSocket简介 短连接:在传统的Http协议中,客户端和服务器端的通信方式是短连接的方式,也就是服务器端并不会保持一个和客户端的连接,在消息发送后,会断开这个连接,客户端下次通信时,必须再建立和服务器的新连接,这就是短连接.在短链接的情况下,客户端必须不停的主动发起请求,而服务器始终被动的响应请求,来推送回数据.这种方式用到游戏开发中,显然是不适合的. 长连接:那么与之相对的就是长连接了.在长连接的情况下,客户端和服务器端始终保持一条有效的连接,那么客户端并不需要不停的主动发送消息

Java网络编程二:Socket详解

Socket又称套接字,是连接运行在网络上两个程序间的双向通讯的端点. 一.使用Socket进行网络通信的过程 服务端:服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户端的连接请求. 客户端:客户端程序根据你服务器所在的主机名和端口号发出连接请求. 两者之间的通信是通过Socket完成的,我们可以认为Socket是两个城市之间的交通工具,有了它,就可以在两个城市之间穿梭了. Socket通信示例 主机A的应用程序和主机B的应用程序通信,必须通过Socket建立连接,而建立

网络编程二

一.为什么要用网路编程? 首先我们要明确一个问题,为什么要用网络编程?因为我们所写的代码程序不只是给自己看的,自己玩的,那样就没什么意义了. 网络编程的意义就是将很多的电脑连接起来共享你们之间的文件 二.软件开发的架构 软件开发的架构有两种 1. c/s架构 c/s 即:Client与Server 架构简单的说就是客户端与服务器架构.这种架构也是从用户层面(也可以是物理层面)来划分的. 2.B/S架构 B/S即:Browser与Server,大概意思就是浏览器端与服务器端架构.这种架构是从用户层

IOS研究之网络编程(二)-Cocoa Streams使用详解

 本文以及相关的系列文章是我总结的iOS网络开发方面的知识点,本文是第二篇,主要分析了Cocoa Streams中的几个重要类 Cocoa Streams实际上是Objective-C对CFNetwork的简单封装,主要包含了三个类:NSStream, NSInputStream, and NSOutputStream.本部分的接口接口比较简单,用法一目了然.我在这里就只列出接口,方便查阅.对CFNnework不明白的看IOS研究之网络编程(一)-CFNetwork使用详解 NSStream