Project1

标题: C++服务端(客户端下回写,写好客户端之后实现QQ的聊天效果) [打印本页]

作者: B612    时间: 2019-8-23 08:13
标题: C++服务端(客户端下回写,写好客户端之后实现QQ的聊天效果)
/*
如果你发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. }
复制代码

作者: fux2    时间: 2019-8-23 10:11
说实话,没看懂描述部分写的啥意思
帮楼主排了下版
作者: B612    时间: 2019-8-23 11:07
那是C++的注释呀
作者: hyrious    时间: 2019-8-23 11: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 的主循环逻辑不允许某个代码卡住主进程太久,否则游戏就玩不下去了。



以上三题都有现成的实现或参考,请在做不出来时好好使用搜索引擎。
作者: B612    时间: 2019-8-23 12:05
/*修改自己的昵称
显示所有可加入的群
加群
出群
提升为管理
踢人(需要先有管理权)
发送消息
以及其他任何你觉得需要的功能
*/
昵称其实就是字符串
可加入的群那就是另一个服务端
加群就是往允许发言的人的字符串数组加上用户的名字
出群就是去除嘛
管理功能,那就可以控制字符串数组嘛
发送消息,就是我下回要写的客户端
作者: guoxiaomi    时间: 2019-8-23 12:09
虽然不是很懂,但我推荐使用hack.chat




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1