设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2776|回复: 5
打印 上一主题 下一主题

[讨论] C++服务端(客户端下回写,写好客户端之后实现QQ的聊天效果)

[复制链接]

Lv3.寻梦者

梦石
0
星屑
959
在线时间
172 小时
注册时间
2019-8-15
帖子
142
跳转到指定楼层
1
发表于 2019-8-23 08:13:30 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
/*
如果你发A,那服务器就会发B发C,服务器就会发D,类似于人工客服
当然,如果客户端发信息的话,那只会发出客户端发的字符串
摁exit服务器关闭线程
*/
  1. #include<bits/stdc++.h>
  2. #include "winsock.h"
  3. #pragma comment(lib,"ws2_32.lib")
  4. using namespace std;
  5. DWORD WINAPI threadpro(LPVOID pParam) {
  6.         SOCKET hsock=(SOCKET)pParam;
  7.         char buffer[1024];
  8.         char sendBuffer[1024];
  9.         if(hsock!=INVALID_SOCKET)
  10.                 cout<<"开始使用\n";
  11.         for(;;) {
  12.                 int num=recv(hsock,buffer,1024,0);
  13.                 if(num>=0)
  14.                         cout<<"你:"<<buffer<<"\n";
  15.                 if(!strcmp(buffer,"A")) {
  16.                         memset(sendBuffer,0,1024);
  17.                         strcpy(sendBuffer,"B");
  18.                         int ires=send(hsock,sendBuffer,sizeof(sendBuffer),0);
  19.                         cout<<"服务器:"<<sendBuffer<<"\n";
  20.                 } else if(!strcmp(buffer,"C")) {
  21.                         memset(sendBuffer,0,1024);
  22.                         strcpy(sendBuffer,"D");
  23.                         int ires=send(hsock,sendBuffer,sizeof(sendBuffer),0);
  24.                         cout<<"服务器:"<<sendBuffer<<"\n";
  25.                 } else if(!strcmp(buffer,"exit")) {
  26.                         cout<<"关闭服务器\n";
  27.                         return 0;
  28.                 }
  29.         }
  30.         return 0;
  31. }
  32. int main(void) {
  33.         SetConsoleTitle("服务端");
  34.         WSADATA wsd;
  35.         WSAStartup(MAKEWORD(2,2),&wsd);
  36.         SOCKET m_SockServer;
  37.         sockaddr_in serveraddr;
  38.         sockaddr_in serveraddrfrom;
  39.         SOCKET m_Server[20];
  40.         serveraddr.sin_family=AF_INET;
  41.         serveraddr.sin_port=htons(4600);
  42.         serveraddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
  43.         m_SockServer=socket(AF_INET,SOCK_STREAM,0);
  44.         int i=bind(m_SockServer,(sockaddr*)&serveraddr,sizeof(serveraddr));
  45.         cout<<i<<"\n";
  46.         int iMaxConnect=10;
  47.         int iConnect=0;
  48.         int iLisRet;
  49.         char buf[]="这是服务器\0";
  50.         char WarnBuf[]="这是最大的连接数了\0";
  51.         int len=sizeof(sockaddr);
  52.         for(;;) {
  53.                 iLisRet=listen(m_SockServer,0);
  54.                 m_Server[iConnect]=accept(m_SockServer,(sockaddr*)&serveraddrfrom,&len);
  55.                 if(m_Server[iConnect]!=INVALID_SOCKET) {
  56.                         int ires=send(m_Server[iConnect],buf,sizeof(buf),0);
  57.                         cout<<"接收:"<<ires<<"\n";
  58.                         iConnect++;
  59.                         if(iConnect>iMaxConnect) {
  60.                                 int ires=send(m_Server[iConnect],WarnBuf,sizeof(WarnBuf),0);
  61.                         } else {
  62.                                 HANDLE m_Handle;
  63.                                 DWORD nThreadld=0;
  64.                                 m_Handle=(HANDLE)::CreateThread(NULL,0,threadpro,(LPVOID)m_Server[--iConnect],0,&nThreadld);
  65.                         }
  66.                 }
  67.                 WSACleanup();
  68.         }
  69. }
复制代码

Lv5.捕梦者 (版主)

梦石
1
星屑
23994
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

6
发表于 2019-8-23 12:09:29 | 只看该作者
虽然不是很懂,但我推荐使用hack.chat
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
959
在线时间
172 小时
注册时间
2019-8-15
帖子
142
5
 楼主| 发表于 2019-8-23 12:05:35 | 只看该作者
/*修改自己的昵称
显示所有可加入的群
加群
出群
提升为管理
踢人(需要先有管理权)
发送消息
以及其他任何你觉得需要的功能
*/
昵称其实就是字符串
可加入的群那就是另一个服务端
加群就是往允许发言的人的字符串数组加上用户的名字
出群就是去除嘛
管理功能,那就可以控制字符串数组嘛
发送消息,就是我下回要写的客户端
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9677
在线时间
570 小时
注册时间
2017-9-28
帖子
208
4
发表于 2019-8-23 11:33:33 | 只看该作者
本帖最后由 hyrious 于 2019-8-23 14:25 编辑

既然你已经了解了 Socket 编程的基本原理,那么来做几个拓展练习吧!(以下练习没有明显的难易之分)

1. 实现一个 “QQ 群” 的服务端

即实现以下功能:

  • 修改自己的昵称
  • 显示所有可加入的群
  • 加群
  • 出群
  • 提升为管理
  • 踢人(需要先有管理权)
  • 发送消息
  • 以及其他任何你觉得需要的功能

具体效果就是 “一问一答” 的形式,例如发送 "USER 新昵称" 给服务器,服务器返回一句 "已修改为 新昵称" 。

参考消息协议如下,你也可以再次修改它以便实现:

  1. USER <nickname>
  2.     修改昵称为 nickname
  3. LIST [#channel]
  4.     列出所有名字包含 #channel 的群,若未给参数则列出所有群
  5. JOIN <#channel>
  6.     加入名字为 #channel 的群
  7. PART [#channel]
  8.     退出所有名字包含 #channel 的群,若未给参数则退出所有群
  9. OPERATOR <password>
  10.     使用暗号 password 提升为管理员
  11. KICK <#channel> <user>
  12.     从 #channel 群里踢出名字为 user 的人,此功能需要先提升为管理员
  13. PRIVMSG (<#channel> | <user>) <message>
  14.     发送消息 message 给 #channel 群或 user 用户
  15. PING <message>
  16.     测试功能:发送消息 message 给服务器
  17. QUIT
  18.     退出程序,关闭 Socket 连接
  19. HELP
  20.     显示帮助说明

  21. 注:尖括号<参数>表示必须填写,方括号[参数]表示可以填可以不填
复制代码

为了再次简化代码方便实现,你可以规定最多有 200 个客户端同时连接,每条消息长度不超过 768 字节等,你也可以增加其他限制以方便实现。



2. 阅读 WebSocket 协议的细节,用 Socket 实现一个 WebSocket

或者也可以把题目中的 WebSocket 改为 CGI 协议,应该会更容易一些。

3. 寻找一个 WebSocket 库,或直接使用上一题的结果,将其封装为适合 RGSS 调用的 dll

题中 “适合” 的意思是不能卡住主进程,RGSS 的主循环逻辑不允许某个代码卡住主进程太久,否则游戏就玩不下去了。



以上三题都有现成的实现或参考,请在做不出来时好好使用搜索引擎。
喵喵喵
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
959
在线时间
172 小时
注册时间
2019-8-15
帖子
142
3
 楼主| 发表于 2019-8-23 11:07:00 | 只看该作者
那是C++的注释呀
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42349
在线时间
7599 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

2
发表于 2019-8-23 10:11:23 | 只看该作者
说实话,没看懂描述部分写的啥意思
帮楼主排了下版
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-16 04:29

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表