zoukankan      html  css  js  c++  java
  • MMORPG大型游戏设计与开发(part1 of net)

      网络模块的设计,是大型多人在线游戏中比较重要的一部分。我之所以将网络模块放到最前面,是因为许许多多的开发者面对这一块的时候充满了疑惑,而且也觉得很神秘和深奥。这些我们面对到的困难,其实是由于我们对这方面了解的不足以及太过陌生。

      本次设计中参考到了天龙八部/武侠世界的网络模块的设计,进行了封装调整,而且天龙八部其实也参考了韩国经典网游的设计,所以在稳定这方面还是有一定的积累。

      在前面的构架中,大家可以看到一次交互的大致流程图,玩家登陆、创建角色、删除角色、选择角色等都由登陆服务器(login)进行负责,而玩家进入游戏后是直接跟游戏服务器(server)进行交互的,而公用数据则是由中心服务器(world)处理。这样分配的好处,是让各个功能各司其职,于服务器来说也就是分压的模式,同时对网络模块来说也减轻了不少压力。

      在本次设计中,用到的是套接字(socket)来进行tcp的网络交互访问,在处理多对一的网络访问中,会用到多线程。所以我在这里首先会介绍下套接字和多线程。

      1、什么是套接字?

      多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口。

      一个简单的例子,下面为linux/windows通用。

      1)服务器(server)

    复制代码
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<errno.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    
    #define MAXLINE 4096
    
    int main(int argc, char** argv) {
      int listenfd, connfd;
      struct sockaddr_in servaddr;
      char buff[4096];
      int n;
    
      if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
        printf("create socket error: %s(errno: %d)
    ", strerror(errno), errno);
        exit(0);
      }
      printf("listenfd: %d
    ", listenfd);
      memset(&servaddr, 0, sizeof(servaddr));
      servaddr.sin_family = AF_INET;
      servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
      servaddr.sin_port = htons(6666);
    
      if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {
        printf("bind socket error: %s(errno: %d)
    ",strerror(errno),errno);
        exit(0);
      }
    
      if (listen(listenfd, 10) == -1) {
        printf("listen socket error: %s(errno: %d)
    ",strerror(errno),errno);
        exit(0);
      }
    
      printf("======waiting for client's request======
    ");
      while (1) {
        if ((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1) {
          printf("accept socket error: %s(errno: %d)", strerror(errno), errno);
          continue;
        }
        n = recv(connfd, buff, MAXLINE, 0);
        buff[n] = '';
        printf("recv msg from client: %s
    ", buff);
        close(connfd);
      }
      close(listenfd);
    }
    复制代码

      2)客户端(client)

    复制代码
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<errno.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    
    #define MAXLINE 4096
    
    int main(int argc, char** argv) {
      int sockfd, n;
      char recvline[4096], sendline[4096];
      struct sockaddr_in servaddr;
    
      if (argc != 2) {
        printf("usage: ./client <ipaddress>
    ");
        exit(0);
      }
    
      if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("create socket error: %s(errno: %d)
    ", strerror(errno), errno);
        exit(0);
      }
        
      printf("sockfd: %d
    ", sockfd);
      memset(&servaddr, 0, sizeof(servaddr));
      servaddr.sin_family = AF_INET;
      servaddr.sin_port = htons(6666);
      if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
        printf("inet_pton error for %s
    ", argv[1]);
        exit(0);
      }
    
      if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
        printf("connect error: %s(errno: %d)
    ", strerror(errno), errno);
        exit(0);
      }
    
      printf("send msg to server: 
    ");
      fgets(sendline, 4096, stdin);
      if (send(sockfd, sendline, strlen(sendline), 0) < 0) {
        printf("send msg error: %s(errno: %d)
    ", strerror(errno), errno);
        exit(0);
      }
    
      close(sockfd);
      exit(0);
    }
    复制代码

      服务器的模式:创建(socket)->绑定(bind)->监听(listen)->等待连接(accept)->接收数据(recv)/发送数据(send)

      客户端的模式:创建(socket)->连接(connect)->接收数据(recv)/发送数据(send)

      2、什么是多线程?C++的多线程如何实现?

      这方面我就不多介绍了,这个入门介绍已经解释的很清楚:http://blog.163.com/zhaojingong@126/blog/static/799089922010814104312911/

  • 相关阅读:
    http://blog.csdn.net/zhang_xinxiu/article/details/38655311
    三分钟了解Activity工作流
    在eclipse中设计BPMN 2.0工作流定义的根本步骤
    http://blog.csdn.net/bluejoe2000/article/details/39521405#t9
    activity的测试工程activiti-explorer使用
    如何让Activiti-Explorer使用sql server数据库
    Java中对List集合排序的两种方法
    常用 Git 命令清单
    推荐!手把手教你使用Git
    理解RESTful架构
  • 原文地址:https://www.cnblogs.com/liuzhi/p/4084556.html
Copyright © 2011-2022 走看看