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

View Code

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[100] = {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[2000];
 33
 34 while(1)
 35 {
 36     int cc = recv(sock, buf, BUFLEN, 0);   //cc为接收的字符数
 37     if(cc == SOCKET_ERROR|| cc == 0)
 38     {
 39         printf("Error: %d.----",GetLastError());
 40         printf("与服务器断开连接!\n");
 41         CloseHandle(hThread);
 42         (void)closesocket(sock);
 43         break;
 44     }
 45     else if(cc > 0)
 46     {
 47     //    buf[cc] = '\0';
 48         printf("%s\n",buf);
 49     //    printf("输入数据(exit退出):  \n");
 50     }
 51 }
 52     return 0;
 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 = "5050";          /* 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, 0, 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,0);
 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, 0,Chat, NULL, 0, &threadID);
 82     printf(" \t\t\t\t 【您可以自由发言】\n\n");
 83 while(1)
 84 {
 85     char buf1[2000];
 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), 0);
 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 0;                           /* exit */
106 }

View Code

【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 多人聊天室相关推荐

  1. 【Java Socket】TCP协议的多人聊天室

    最近老师叫我们做一个基于Socket的多人聊天室,网上很多教程都只讲了如何通过Socket来建立连接以及通过控制台一遍打印证明连接已经完成但还没有具体实现多人聊天.这次我整理了一下自己的实现代码,希望 ...

  2. c语言tcp多线程聊天室,66 网络编程(五)——TCP多线程实现多人聊天室

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

  3. java多人聊天室的实验任务_Java基于中介者模式实现多人聊天室功能示例

    本文实例讲述了Java基于中介者模式实现多人聊天室功能.分享给大家供大家参考,具体如下: 一 模式定义 中介者模式,用一个中介对象来封装一系列对象之间的交互,使各个对象中不需要显示地引用其他对象实例, ...

  4. TCP服务器客户端编程流程

    TCP服务器客户端编程流程 TCP编程流程 主机字节序列和网络字节序列 套接字地址结构 通用socket地址结构 一般使用会定义一个专用的套接字结构 IP地址转换函数 网络编程接口 TCP服务段代码实 ...

  5. 基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信

    基于Python Tkiner.thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信 完整代码下载地址:基于Python Tkiner.thread与soc ...

  6. TCP创建多人聊天室

    群聊-聊天室 群聊:任何时候,任何一个客户端都可以向其它客户端发送和接受数据,服务器只起到转发的作用. 1.首先创建一个聊天室的简易版(版本1). 需求:可以多个用户同时访问服务端,并且可以不断各自请 ...

  7. linux下多人聊天室

    客户端 一个在Linux下可以使用的聊天软件,要求至少实现如下功能:1. 采用Client/Server架构2. Client A 登陆聊天服务器前,需要注册自己的ID和密码3. 注册成功后,Clie ...

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

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

  9. [游戏服务器]第一章:多人聊天室-服务端

    游戏服务器 多人房间 高并发 低延时 数据可靠 ... 那么怎么去实现这些功能呢,下面我将会带着大家一起去探寻游戏服务器的奥秘 我不是巨人,我只是站在巨人的肩膀上 我将会分城多个章节去研究游戏服务器的 ...

最新文章

  1. 如果某路由器到达目的网络有三种方式:通过RIP;通过静态路由;通过默认路由,那么路由器会根据哪种方式进行转发数据包?( )
  2. POST和PUT HTTP REQUEST有什么区别?
  3. windows7系统损坏修复_修复损坏的系统文件,就用系统文件检查器SFC,简单高效...
  4. c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast
  5. 第三方app_官方打不过第三方APP之 知乎 篇
  6. C/C++ 错误处理
  7. MSET算法参差分析(一)
  8. 钢铁侠或漫威中有哪些黑科技?
  9. HOJ 1568 Fibonacci(对数,数列通项公式)
  10. html是什么意思 它是一种什么样的语言,HTML 是什么?
  11. 基于Python 实现 Spirent TestCenter 自动化
  12. mysql错误1548 Cannot load from mysql.proc的最终解决方法
  13. 中公教育python教师_为什么中公教育、华图的老师不自己去考公务员?
  14. <JVM笔记:内存与垃圾回收>13-垃圾回收器
  15. 【笔记】MATLAB 批量注释/批量取消注释
  16. NIST Big Data Interoperability
  17. mysql select into
  18. android收藏功能demo,Android使用Realm数据库实现App中的收藏功能(代码详解)
  19. classes是什么意思怎么读_“学生上课”是“take a class”,那“老师上课”用英语怎么说?...
  20. Java菜单(菜单条、菜单和菜单项)

热门文章

  1. MySQL数据库环境使用全过程
  2. 优雅的理解 call 和 apply 的使用方法
  3. web存储中cookie、session区别
  4. 面向对象三大特性一一封装(encapsulation)
  5. STP 根桥、根port、指定port是怎样选举的
  6. 介绍并扩展Fitnesse的测试模块化机制:Scenario
  7. 入职体检体检错了_我们如何更新入职体验并获得更多用户
  8. router路由react_使用React Router在React中受保护的路由
  9. 初学者css常见问题_5分钟内学习CSS Grid-初学者教程
  10. ESXi6.5环境搭建(一:VMware Workstations 12 Pro 环境的安装及配置)