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 字节等,你也可以增加其他限制以方便实现。

(, 下载次数: 109)

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! X5.0