本次实验利用TCP/IP, 语言环境为 C/C++

利用套接字Socket编程,以及线程处理,

实现Server/CLient 之间多人的聊天系统的基本功能。

结果大致如:

下面贴上代码(参考参考...)

Server 部分:

  1. /* TCPdtd.cpp - main, TCPdaytimed */
  2.  
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <winsock2.h>
  6. #include <time.h>
  7. #include "conio.h"
  8. #include <windows.h>
  9. #include <process.h>
  10. #include <math.h>
  11.  
  12. #define QLEN 5
  13. #define WSVERS MAKEWORD(2, 0)
  14. #define BUFLEN 2000 // 缓冲区大小
  15. #pragma comment(lib,"ws2_32.lib") //winsock 2.2 library
  16.  
  17. SOCKET msock, ssock; /* master & slave sockets */
  18. SOCKET sockets[] = {NULL};
  19.  
  20. int cc;
  21. char *pts; /* pointer to time string */
  22. time_t now; /* current time */
  23. char buf[]; /* buffer */
  24. char *input;
  25. HANDLE hThread1,hThread[] = {NULL};
  26. unsigned int threadID,ThreadID[],number;
  27.  
  28. struct sockaddr_in fsin;
  29. struct sockaddr_in Sin;
  30.  
  31. unsigned int __stdcall Chat(PVOID PM)
  32. {
  33. char buf1[];
  34. char buf2[];
  35. char buf3[];
  36. char buf4[];
  37. (void) time(&now);
  38. pts = ctime(&now);
  39. sockets[number] = ssock;
  40. SOCKET sock = ssock;
  41. ThreadID[number] = threadID;
  42. unsigned int threadid = threadID;
  43. sprintf(buf1," 时间: %s \t【我的线程号: %d 】\n",pts,threadid);
  44. (void) send(sock,buf1, sizeof(buf1), );
  45. sprintf(buf2," 线程号 <%d> 客户<IP:%s 端口:%d> enter \n",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port);
  46. printf("%s ",buf2);
  47. printf("\t将自动把此数据发送给所有客户! \n");
  48. for(int i=;i<=number;i++)
  49. {
  50. if(sockets[i] != NULL && sockets[i] != sock)
  51. {
  52. (void) send(sockets[i],buf2, sizeof(buf2), );
  53. printf(" 发送至线程号<%d>成功!\n",ThreadID[i]);
  54. }
  55. }
  56. printf(" \n");
  57.  
  58. flag1:cc = recv(sock, buf3, BUFLEN, ); //cc为接收的字符数
  59. if(cc == SOCKET_ERROR|| cc == )
  60. {
  61. (void) time(&now);
  62. pts = ctime(&now);
  63. sprintf( buf3," 线程号 <%d> 客户<IP:%s 端口:%d> leave ! \n \t\t时间: %s",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,pts);
  64. sock = NULL;
  65. sockets[number] = NULL;
  66. CloseHandle(hThread[number]);
  67. printf("%s ", buf3);
  68. printf("\t将自动把此数据发送给所有客户! \n");
  69. for(int i=;i<=number;i++)
  70. {
  71. if(sockets[i] != NULL && sockets[i] != sock)
  72. {
  73. (void) send(sockets[i], buf3, sizeof(buf3), );
  74. printf(" 发送至线程号<%d>成功!\n",ThreadID[i]);
  75. }
  76. }
  77. printf(" \n");
  78. }
  79.  
  80. else if(cc > )
  81. {
  82. (void) time(&now);
  83. pts = ctime(&now);
  84. sprintf(buf4," 线程号 <%d> 客户<IP:%s 端口:%d>说 :%s \n \t\t时间 : %s",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,buf3,pts);
  85.  
  86. printf("%s ",buf4);
  87. printf("\t将自动把此数据发送给所有客户! \n");
  88. for(int i=;i<=number;i++)
  89. {
  90. if(sockets[i] != NULL && sockets[i] != sock)
  91. {
  92. (void) send(sockets[i],buf4, sizeof(buf4), );
  93. printf(" 发送至线程号<%d>成功!\n",ThreadID[i]);
  94. }
  95. }
  96. printf(" \n");
  97.  
  98. goto flag1;
  99. }
  100. (void) closesocket(sock);
  101.  
  102. return ;
  103. }
  104.  
  105. /*------------------------------------------------------------------------
  106. * main - Iterative TCP server for DAYTIME service
  107. *------------------------------------------------------------------------
  108. */
  109. void main(int argc, char *argv[])
  110. /* argc: 命令行参数个数, 例如:C:\> TCPdaytimed 8080
  111. argc=2 argv[0]="TCPdaytimed",argv[1]="8080" */
  112. {
  113. int alen; /* from-address length */
  114. WSADATA wsadata;
  115. char *service = "";
  116. WSAStartup(WSVERS, &wsadata); //加载 winsock 2.2 library
  117. msock = socket(PF_INET, SOCK_STREAM, ); //生成套接字。TCP协议号=6, UDP协议号=17
  118. memset(&Sin, , sizeof(Sin));
  119. Sin.sin_family = AF_INET;
  120. Sin.sin_addr.s_addr = INADDR_ANY; //指定绑定接口的IP地址。INADDR_ANY表示绑定(监听)所有的接口。
  121. Sin.sin_port = htons((u_short)atoi(service)); //atoi--把ascii转化为int,htons - 主机序(host)转化为网络序(network), s(short)
  122. bind(msock, (struct sockaddr *)&Sin, sizeof(Sin)); // 绑定端口号(和IP地址)
  123. listen(msock, ); //队列长度为5
  124.  
  125. printf("\t\t\t\t Chat 多人聊天程序 \n");
  126. printf("\t\t\t\t (Server) \n");
  127. (void) time(&now);
  128. pts = ctime(&now);
  129. printf("\t\t\t 时间 :%s",pts);
  130. number = -;
  131. while() //检测是否有按键
  132. {
  133. alen = sizeof(struct sockaddr);
  134. ssock = accept(msock, (struct sockaddr *)&fsin, &alen);
  135. number ++;
  136. hThread[number] = (HANDLE)_beginthreadex(NULL, ,Chat,NULL, , &threadID);
  137. }
  138. (void) closesocket(msock);
  139. WSACleanup(); //卸载载 winsock 2.2 library
  140. }

Client 部分:

  1. /* TCPClient.cpp -- 用于传递struct */
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <winsock2.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include <windows.h>
  8. #include <process.h>
  9. #include <math.h>
  10.  
  11. #define BUFLEN 2000 // 缓冲区大小
  12. #define WSVERS MAKEWORD(2, 0) // 指明版本2.0
  13. #pragma comment(lib,"ws2_32.lib") // 指明winsock 2.0 Llibrary
  14.  
  15. /*------------------------------------------------------------------------
  16. * main - TCP client for DAYTIME service
  17. *------------------------------------------------------------------------
  18. */
  19.  
  20. SOCKET sock,sockets[] = {NULL}; /* socket descriptor */
  21. // int cc; /* recv character count */
  22. char *packet = NULL; /* buffer for one line of text */
  23. char *pts,*input;
  24. HANDLE hThread;
  25. unsigned threadID;
  26.  
  27. unsigned int __stdcall Chat(PVOID PM )
  28. {
  29. time_t now;
  30. (void) time(&now);
  31. pts = ctime(&now);
  32. char buf[];
  33.  
  34. while()
  35. {
  36. int cc = recv(sock, buf, BUFLEN, ); //cc为接收的字符数
  37. if(cc == SOCKET_ERROR|| cc == )
  38. {
  39. printf("Error: %d.----",GetLastError());
  40. printf("与服务器断开连接!\n");
  41. CloseHandle(hThread);
  42. (void)closesocket(sock);
  43. break;
  44. }
  45. else if(cc > )
  46. {
  47. // buf[cc] = '\0';
  48. printf("%s\n",buf);
  49. // printf("输入数据(exit退出): \n");
  50. }
  51. }
  52. return ;
  53. }
  54.  
  55. int main(int argc, char *argv[])
  56. {
  57. time_t now;
  58. (void) time(&now);
  59. pts = ctime(&now);
  60. char *host = "127.0.0.1"; /* server IP to connect */
  61. // char *host = "172.18.33.155";
  62. // char *host = "172.18.33.93";
  63. // char *host = "172.18.187.1";
  64. char *service = ""; /* server port to connect */
  65. // char *service = "50000";
  66. struct sockaddr_in sin; /* an Internet endpoint address */
  67. WSADATA wsadata;
  68. WSAStartup(WSVERS, &wsadata); /* 启动某版本Socket的DLL */
  69.  
  70. memset(&sin, , sizeof(sin));
  71. sin.sin_family = AF_INET;
  72. sin.sin_port = htons((u_short)atoi(service)); //atoi:把ascii转化为int. htons:主机序(host)转化为网络序(network), s--short
  73. sin.sin_addr.s_addr = inet_addr(host); //如果host为域名,需要先用函数gethostbyname把域名转化为IP地址
  74.  
  75. sock = socket(PF_INET, SOCK_STREAM,);
  76.  
  77. connect(sock, (struct sockaddr *)&sin, sizeof(sin));
  78.  
  79. printf("\t\t\t\tChat 多人聊天程序 \n");
  80. printf("\t\t\t\t (Client) \n");
  81. hThread = (HANDLE)_beginthreadex(NULL, ,Chat, NULL, , &threadID);
  82. printf(" \t\t\t\t 【您可以自由发言】\n\n");
  83. while()
  84. {
  85. char buf1[];
  86.  
  87. // scanf("%s",&buf1);
  88.  
  89. gets_s(buf1);
  90. if(!strcmp(buf1 ,"exit"))
  91. goto end;
  92.  
  93. (void) send(sock,buf1, sizeof(buf1), );
  94. (void) time(&now);
  95. pts = ctime(&now);
  96. printf(" 发送成功! ------时间: %s\n",pts);
  97. }
  98.  
  99. end: CloseHandle(hThread);
  100. closesocket(sock);
  101. WSACleanup(); /* 卸载某版本的DLL */
  102.  
  103. printf("按回车键继续...");
  104. getchar();
  105. return ; /* exit */
  106. }

【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 "多人聊天室"的更多相关文章

  1. 【Echo】实验 -- 实现 C/C++下TCP, 服务器/客户端 通讯

    本次实验利用TCP/IP, 语言环境为 C/C++ 利用套接字Socket编程,实现Server/CLient 之间简单的通讯. 结果应为类似所示: 下面贴上代码(参考参考...) Server 部分 ...

  2. 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

    原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  3. 66 网络编程(五)——TCP多线程实现多人聊天室

    思路 客户端读写各一个类,可以使内部类,实现Runnable.读写类都与服务器端建立连接,一个收,一个发. 客户端实现接收和转发.多线程实现每个客户端的连接(使与各客户端的连接独立). 服务器端中创建 ...

  4. 【Echo】实验 -- 实现 C/C++下UDP, 服务器/客户端 通讯

    本次实验利用UDP协议, 语言环境为 C/C++ 利用套接字Socket编程,实现Server/CLient 之间简单的通讯. 结果应为类似所示: 下面贴上代码(参考参考...) Server 部分: ...

  5. 基于tcp和多线程的多人聊天室-C语言

    之前在学习关于网络tcp和多线程的编程,学了知识以后不用一下总绝对心虚,于是就编写了一个基于tcp和多线程的多人聊天室. 具体的实现过程: 服务器端:绑定socket对象->设置监听数-> ...

  6. 采用PHP实现”服务器推”技术的聊天室

      传统的B/S结构的应用程序,都是采用”客户端拉”结束来实现客户端和服务器端的数据交换. 本文将通过结合Ticks(可以参看我的另外一篇文章:关于PHP你可能不知道的-PHP的事件驱动化设计),来实 ...

  7. TCP服务器/客户端代码示例

    TCP服务器代码: #include <errno.h> #include <string.h> #include <stdlib.h> #include < ...

  8. 以C#编写的Socket服务器的Android手机聊天室Demo

    内容摘要 1.程序架构 2.通信协议 3.服务器源代码 4.客户端源代码 5.运行效果 一.程序架构 在开发一个聊天室程序时,我们可以使用Socket.Remoting.WCF这些具有双向通信的协议或 ...

  9. Java进阶:基于TCP通信的网络实时聊天室

    目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...

随机推荐

  1. TSQL--TOP选项

    TOP选项需要依据ORDER来选取记录,可以依据行数和百分比来选取记录 按照行数来选取10行记录 SELECT TOP(10) * FROM T1 ORDER BY ID 按照行数来选取10%的记录 ...

  2. ASP.NET基于Aspose.Words插入Word水印以及多个水印

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Da ...

  3. Javascript 535种方式!!!实现页面重载

    原文地址: http://www.phpied.com/files/location-location/location-location.html 完全出于好玩,竟然有人整理了500多种方法来实现刷 ...

  4. 加固apk的开发者最常面对的十种问题

    欢迎访问网易云社区,了解更多网易技术产品运营经验. 因为工信部对移动App应用安全过检要求日益增多,不加固大都达不到工信部的要求,同时开发者加固App大都是为了防止以下10个检测项出现问题,影响App ...

  5. Exp1 PC平台逆向破解 20164323段钊阳

    实验目标 学习两种方法运行代码片段,并学习如何注入运行任何Shellcode. 三个实验内容如下: 1.手工修改可执行文件,改变程序执行流程,直接跳转到getshell函数 2.利用foo函数的bof ...

  6. [Objective-C语言教程]Posing(29)

    Posing,顾名思义,意思是“冒充”,它跟categories类似,但本质上不一样,Posing存在的目的在于子类可以冒充父类,使得后续的代码无需把父类修改为子类,就可以很方便的让父类表现成子类的行 ...

  7. Protobuf底层存储原理

    参考官网, 序列化原理 底层二进制存储 message Test1 { optional int32 a = 1; } 并设置为a=150,序列化到一个文件中,查看文件,得到下面的二进制: 08 96 ...

  8. leetcode-844-比较含退格的字符串(用vector取代stack)

    题目描述: 给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果. # 代表退格字符. 示例 1: 输入:S = "ab#c", T = ...

  9. 本地搭建sass运行环境

    1.安装node.js 安装文件为msi文件,可到node.js官网下载安装包,下载路径为:https://nodejs.org/en/download/ 安装路径为默认路径,安装完成之后配置环境变量 ...

  10. easy-mock本地部署成功,访问报错:EADDRNOTAVAIL 0.0.0.0:7300 解决方案

    easy-mock本地部署成功后,迫不及待的想看看是否能正常访问,执行命令 npm run dev 启动项目,访问 127.0.0.1:7300 ,结果郁闷的是报错:EADDRNOTAVAIL 0.0 ...