【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 "多人聊天室"
本次实验利用TCP/IP, 语言环境为 C/C++
利用套接字Socket编程,以及线程处理,
实现Server/CLient 之间多人的聊天系统的基本功能。
结果大致如:
下面贴上代码(参考参考...)
Server 部分:
- /* TCPdtd.cpp - main, TCPdaytimed */
- #include <stdlib.h>
- #include <stdio.h>
- #include <winsock2.h>
- #include <time.h>
- #include "conio.h"
- #include <windows.h>
- #include <process.h>
- #include <math.h>
- #define QLEN 5
- #define WSVERS MAKEWORD(2, 0)
- #define BUFLEN 2000 // 缓冲区大小
- #pragma comment(lib,"ws2_32.lib") //winsock 2.2 library
- SOCKET msock, ssock; /* master & slave sockets */
- SOCKET sockets[] = {NULL};
- int cc;
- char *pts; /* pointer to time string */
- time_t now; /* current time */
- char buf[]; /* buffer */
- char *input;
- HANDLE hThread1,hThread[] = {NULL};
- unsigned int threadID,ThreadID[],number;
- struct sockaddr_in fsin;
- struct sockaddr_in Sin;
- unsigned int __stdcall Chat(PVOID PM)
- {
- char buf1[];
- char buf2[];
- char buf3[];
- char buf4[];
- (void) time(&now);
- pts = ctime(&now);
- sockets[number] = ssock;
- SOCKET sock = ssock;
- ThreadID[number] = threadID;
- unsigned int threadid = threadID;
- sprintf(buf1," 时间: %s \t【我的线程号: %d 】\n",pts,threadid);
- (void) send(sock,buf1, sizeof(buf1), );
- sprintf(buf2," 线程号 <%d> 客户<IP:%s 端口:%d> enter \n",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port);
- printf("%s ",buf2);
- printf("\t将自动把此数据发送给所有客户! \n");
- for(int i=;i<=number;i++)
- {
- if(sockets[i] != NULL && sockets[i] != sock)
- {
- (void) send(sockets[i],buf2, sizeof(buf2), );
- printf(" 发送至线程号<%d>成功!\n",ThreadID[i]);
- }
- }
- printf(" \n");
- flag1:cc = recv(sock, buf3, BUFLEN, ); //cc为接收的字符数
- if(cc == SOCKET_ERROR|| cc == )
- {
- (void) time(&now);
- pts = ctime(&now);
- sprintf( buf3," 线程号 <%d> 客户<IP:%s 端口:%d> leave ! \n \t\t时间: %s",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,pts);
- sock = NULL;
- sockets[number] = NULL;
- CloseHandle(hThread[number]);
- printf("%s ", buf3);
- printf("\t将自动把此数据发送给所有客户! \n");
- for(int i=;i<=number;i++)
- {
- if(sockets[i] != NULL && sockets[i] != sock)
- {
- (void) send(sockets[i], buf3, sizeof(buf3), );
- printf(" 发送至线程号<%d>成功!\n",ThreadID[i]);
- }
- }
- printf(" \n");
- }
- else if(cc > )
- {
- (void) time(&now);
- pts = ctime(&now);
- sprintf(buf4," 线程号 <%d> 客户<IP:%s 端口:%d>说 :%s \n \t\t时间 : %s",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,buf3,pts);
- printf("%s ",buf4);
- printf("\t将自动把此数据发送给所有客户! \n");
- for(int i=;i<=number;i++)
- {
- if(sockets[i] != NULL && sockets[i] != sock)
- {
- (void) send(sockets[i],buf4, sizeof(buf4), );
- printf(" 发送至线程号<%d>成功!\n",ThreadID[i]);
- }
- }
- printf(" \n");
- goto flag1;
- }
- (void) closesocket(sock);
- return ;
- }
- /*------------------------------------------------------------------------
- * main - Iterative TCP server for DAYTIME service
- *------------------------------------------------------------------------
- */
- void main(int argc, char *argv[])
- /* argc: 命令行参数个数, 例如:C:\> TCPdaytimed 8080
- argc=2 argv[0]="TCPdaytimed",argv[1]="8080" */
- {
- int alen; /* from-address length */
- WSADATA wsadata;
- char *service = "";
- WSAStartup(WSVERS, &wsadata); //加载 winsock 2.2 library
- msock = socket(PF_INET, SOCK_STREAM, ); //生成套接字。TCP协议号=6, UDP协议号=17
- memset(&Sin, , sizeof(Sin));
- Sin.sin_family = AF_INET;
- Sin.sin_addr.s_addr = INADDR_ANY; //指定绑定接口的IP地址。INADDR_ANY表示绑定(监听)所有的接口。
- Sin.sin_port = htons((u_short)atoi(service)); //atoi--把ascii转化为int,htons - 主机序(host)转化为网络序(network), s(short)
- bind(msock, (struct sockaddr *)&Sin, sizeof(Sin)); // 绑定端口号(和IP地址)
- listen(msock, ); //队列长度为5
- printf("\t\t\t\t Chat 多人聊天程序 \n");
- printf("\t\t\t\t (Server) \n");
- (void) time(&now);
- pts = ctime(&now);
- printf("\t\t\t 时间 :%s",pts);
- number = -;
- while() //检测是否有按键
- {
- alen = sizeof(struct sockaddr);
- ssock = accept(msock, (struct sockaddr *)&fsin, &alen);
- number ++;
- hThread[number] = (HANDLE)_beginthreadex(NULL, ,Chat,NULL, , &threadID);
- }
- (void) closesocket(msock);
- WSACleanup(); //卸载载 winsock 2.2 library
- }
Client 部分:
- /* TCPClient.cpp -- 用于传递struct */
- #include <stdlib.h>
- #include <stdio.h>
- #include <winsock2.h>
- #include <string.h>
- #include <time.h>
- #include <windows.h>
- #include <process.h>
- #include <math.h>
- #define BUFLEN 2000 // 缓冲区大小
- #define WSVERS MAKEWORD(2, 0) // 指明版本2.0
- #pragma comment(lib,"ws2_32.lib") // 指明winsock 2.0 Llibrary
- /*------------------------------------------------------------------------
- * main - TCP client for DAYTIME service
- *------------------------------------------------------------------------
- */
- SOCKET sock,sockets[] = {NULL}; /* socket descriptor */
- // int cc; /* recv character count */
- char *packet = NULL; /* buffer for one line of text */
- char *pts,*input;
- HANDLE hThread;
- unsigned threadID;
- unsigned int __stdcall Chat(PVOID PM )
- {
- time_t now;
- (void) time(&now);
- pts = ctime(&now);
- char buf[];
- while()
- {
- int cc = recv(sock, buf, BUFLEN, ); //cc为接收的字符数
- if(cc == SOCKET_ERROR|| cc == )
- {
- printf("Error: %d.----",GetLastError());
- printf("与服务器断开连接!\n");
- CloseHandle(hThread);
- (void)closesocket(sock);
- break;
- }
- else if(cc > )
- {
- // buf[cc] = '\0';
- printf("%s\n",buf);
- // printf("输入数据(exit退出): \n");
- }
- }
- return ;
- }
- int main(int argc, char *argv[])
- {
- time_t now;
- (void) time(&now);
- pts = ctime(&now);
- char *host = "127.0.0.1"; /* server IP to connect */
- // char *host = "172.18.33.155";
- // char *host = "172.18.33.93";
- // char *host = "172.18.187.1";
- char *service = ""; /* server port to connect */
- // char *service = "50000";
- struct sockaddr_in sin; /* an Internet endpoint address */
- WSADATA wsadata;
- WSAStartup(WSVERS, &wsadata); /* 启动某版本Socket的DLL */
- memset(&sin, , sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons((u_short)atoi(service)); //atoi:把ascii转化为int. htons:主机序(host)转化为网络序(network), s--short
- sin.sin_addr.s_addr = inet_addr(host); //如果host为域名,需要先用函数gethostbyname把域名转化为IP地址
- sock = socket(PF_INET, SOCK_STREAM,);
- connect(sock, (struct sockaddr *)&sin, sizeof(sin));
- printf("\t\t\t\tChat 多人聊天程序 \n");
- printf("\t\t\t\t (Client) \n");
- hThread = (HANDLE)_beginthreadex(NULL, ,Chat, NULL, , &threadID);
- printf(" \t\t\t\t 【您可以自由发言】\n\n");
- while()
- {
- char buf1[];
- // scanf("%s",&buf1);
- gets_s(buf1);
- if(!strcmp(buf1 ,"exit"))
- goto end;
- (void) send(sock,buf1, sizeof(buf1), );
- (void) time(&now);
- pts = ctime(&now);
- printf(" 发送成功! ------时间: %s\n",pts);
- }
- end: CloseHandle(hThread);
- closesocket(sock);
- WSACleanup(); /* 卸载某版本的DLL */
- printf("按回车键继续...");
- getchar();
- return ; /* exit */
- }
【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 "多人聊天室"的更多相关文章
- 【Echo】实验 -- 实现 C/C++下TCP, 服务器/客户端 通讯
本次实验利用TCP/IP, 语言环境为 C/C++ 利用套接字Socket编程,实现Server/CLient 之间简单的通讯. 结果应为类似所示: 下面贴上代码(参考参考...) Server 部分 ...
- 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室
原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 66 网络编程(五)——TCP多线程实现多人聊天室
思路 客户端读写各一个类,可以使内部类,实现Runnable.读写类都与服务器端建立连接,一个收,一个发. 客户端实现接收和转发.多线程实现每个客户端的连接(使与各客户端的连接独立). 服务器端中创建 ...
- 【Echo】实验 -- 实现 C/C++下UDP, 服务器/客户端 通讯
本次实验利用UDP协议, 语言环境为 C/C++ 利用套接字Socket编程,实现Server/CLient 之间简单的通讯. 结果应为类似所示: 下面贴上代码(参考参考...) Server 部分: ...
- 基于tcp和多线程的多人聊天室-C语言
之前在学习关于网络tcp和多线程的编程,学了知识以后不用一下总绝对心虚,于是就编写了一个基于tcp和多线程的多人聊天室. 具体的实现过程: 服务器端:绑定socket对象->设置监听数-> ...
- 采用PHP实现”服务器推”技术的聊天室
传统的B/S结构的应用程序,都是采用”客户端拉”结束来实现客户端和服务器端的数据交换. 本文将通过结合Ticks(可以参看我的另外一篇文章:关于PHP你可能不知道的-PHP的事件驱动化设计),来实 ...
- TCP服务器/客户端代码示例
TCP服务器代码: #include <errno.h> #include <string.h> #include <stdlib.h> #include < ...
- 以C#编写的Socket服务器的Android手机聊天室Demo
内容摘要 1.程序架构 2.通信协议 3.服务器源代码 4.客户端源代码 5.运行效果 一.程序架构 在开发一个聊天室程序时,我们可以使用Socket.Remoting.WCF这些具有双向通信的协议或 ...
- Java进阶:基于TCP通信的网络实时聊天室
目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...
随机推荐
- TSQL--TOP选项
TOP选项需要依据ORDER来选取记录,可以依据行数和百分比来选取记录 按照行数来选取10行记录 SELECT TOP(10) * FROM T1 ORDER BY ID 按照行数来选取10%的记录 ...
- ASP.NET基于Aspose.Words插入Word水印以及多个水印
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Da ...
- Javascript 535种方式!!!实现页面重载
原文地址: http://www.phpied.com/files/location-location/location-location.html 完全出于好玩,竟然有人整理了500多种方法来实现刷 ...
- 加固apk的开发者最常面对的十种问题
欢迎访问网易云社区,了解更多网易技术产品运营经验. 因为工信部对移动App应用安全过检要求日益增多,不加固大都达不到工信部的要求,同时开发者加固App大都是为了防止以下10个检测项出现问题,影响App ...
- Exp1 PC平台逆向破解 20164323段钊阳
实验目标 学习两种方法运行代码片段,并学习如何注入运行任何Shellcode. 三个实验内容如下: 1.手工修改可执行文件,改变程序执行流程,直接跳转到getshell函数 2.利用foo函数的bof ...
- [Objective-C语言教程]Posing(29)
Posing,顾名思义,意思是“冒充”,它跟categories类似,但本质上不一样,Posing存在的目的在于子类可以冒充父类,使得后续的代码无需把父类修改为子类,就可以很方便的让父类表现成子类的行 ...
- Protobuf底层存储原理
参考官网, 序列化原理 底层二进制存储 message Test1 { optional int32 a = 1; } 并设置为a=150,序列化到一个文件中,查看文件,得到下面的二进制: 08 96 ...
- leetcode-844-比较含退格的字符串(用vector取代stack)
题目描述: 给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果. # 代表退格字符. 示例 1: 输入:S = "ab#c", T = ...
- 本地搭建sass运行环境
1.安装node.js 安装文件为msi文件,可到node.js官网下载安装包,下载路径为:https://nodejs.org/en/download/ 安装路径为默认路径,安装完成之后配置环境变量 ...
- easy-mock本地部署成功,访问报错:EADDRNOTAVAIL 0.0.0.0:7300 解决方案
easy-mock本地部署成功后,迫不及待的想看看是否能正常访问,执行命令 npm run dev 启动项目,访问 127.0.0.1:7300 ,结果郁闷的是报错:EADDRNOTAVAIL 0.0 ...