|
发表于 2006-1-5 10:39:00
|
显示全部楼层
Re:我的一个毕业论文游戏,大家帮我看看多提意见
4.2.3 套接字I/O模型
对于在Socket,这里我们做一个介绍。在挖网络通讯中我们至少需要一对套接字(Socket),即运行于客户端的CliSocket和运行于服务器端的SerSocket。
其基本的步骤:
(1).首先加载WinSock库,这里涉及到两个函数:WSAStartup()和
WSACleanup()。使用WSAStartup函数可加载WinSock库;在使
用WinSock库之后用WSACleanup函数释放所使用的资源。
(2).创建套接字,建立一个于TCP服务器的连接。
servsocket = socket(AF_INET, SOCK_STREAM, 0) 其中AF_INET是协议簇,SOCK_STREAM为套接字的类型。协议簇与不同的套接字类型组合,用于不同的通信协议。参数“0”的实际意义是指定套接字使用的协议。一般指定为0即可。
(3).填充服务器地址结构
sa为Socket地址结构对象,即struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(servport); // u_long
sa.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // u_short
绑定套接字到服务器地址结构
bind(servsocket, (const sockaddr *)&sa,sizeof(sa));
(4).监听套接字,指示一个套接字进入连接。
Listen(servsock,5)该函数仅被TCP服务器端调用,等待Client端的请
求的到来。这里的参数“5”表示如果多于5个的连接请求同时出现,那
么头5个请求将被放入等待队列中,等候程序处理,而多出的连接将被丢
弃并产生一个错误(WSAECONNREFUSED)。
(5). 循环接受连接请求,
accept(servsocket, (struct sockaddr *)&cliaddr, &len)
该函数也由TCP服务器调用。它从以完成连接队列头返回下一个已完成的连接。如果已完成队列为空,则导致进程进入睡眠状态。这里servsocket即处于监听连接状态的Server端套接字;参数(struct sockaddr *)&cliaddr是接受连接方的地址;len一个整型指针,指向存放cliaddr的缓冲区的长度。
(6).将Buffer中的内容发给客户端和关闭客户端套接字连接
send(clisocket, buff, strlen(buff), 0); /* 发送给客户 */
closesocket(clisocket); /* 关闭与客户的连接 */
(7) .关闭服务套接字连接和释放资源
closesocket(servsocket);
WSACleanup();
以上是利用套接字进行网络通讯的全过程。
4.2.4 多线程编程
Server采用CptrArray指针数组来存放与Client连接的Socket。转发消息的过程主要集中在CptrArray的操作上。对每一个新注册的Client都要穿件一个服务Socket与之相连,并为它分配一个ID同时回送它。这个ID与Socket在
CptrArray中的位置是相关联的。
由于网络的是通过Socket来实现,所以服务器程序的运行更是离不开它。如图所示:
对于上图的单线程和多线程的选择,作如下考虑:
服务器端如果使用单线程,那么当某用户在进行一次更新时,其他的用户的请求将被屏蔽,因为如果同时处理有可能在接受顺序上出现问题而引起系统崩溃。所以服务器端的接收部分应该用线程的方式独立开来,对每次接收的信息起用一个单线程来处理,完成后系统将自动回收。
具体的是方法是在服务器的Server类中建立一个OperateString的内部类,顾名思义,就是对从客户端发送过来的数据报中截取出数据段(String)的处理,
OperateString类继承自Thread类,可以通过Start()函数开启一个新线程执行run()函数中的内容。而run()函数则一个StringTokenizer类通过字符串“&&"把客户端发送过来的String分离为一个String[](数组),然后,按照按照客户端打包的顺序提取属性。这样,每个客户端发送的消息都可以同时进行处理而不需要等待。但是线程操作可能导致系统内数据的紊乱,比如某个函数需要修改数组,在这个时间段里,出现了另一个对该数组修改的请求,那么就有可能造成数据混乱而造引起系统的崩溃。
所以在这里引进一个全局的变量作为标识符locked,在需要修改某个数据的与局前,先判断locked是否为false,是则执行,不是则一直重新判断,一直到该资源被释放,然后该标识设置为true 来锁定资源,在执行完该语句后再将该标识设置为false释放资源。
综上,通过线程的机制,套接字和TCP/IP协议得到简单的网络模型:
|
|