多人聊天室,Windows黑窗口
两个程序:service和client
需要先启动service,再启动client输入IP。

实现步骤
service:

  1. 先创建一个listen
  2. 循环去监听连接请求
  3. 收到一个请求时,先将该连接实例存储在全局的hash_map中
  4. 再创建一个线程去监听该连接发送的消息
  5. 子线程收到消息就向hash_map中所有连接群发消息
  6. 客户端连接到服务器后,创建一个子线程去接收服务器的消息,主线程

client:

  1. 连接服务器
  2. 创建子线程监听服务器的消息
  3. 主线程循环等待用户发送数据

service代码:

#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<Windows.h>
#include<hash_map>
#include<iterator>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib, "pthreadVC2.lib")
#define max_conn_number 20
using namespace std;typedef struct client {int id;char *name;SOCKET socket;
}Client;
pair<int, Client> Pair;
hash_map<int,Client> clients;
const char *fenge = ":";
const char *wellcome_str = "welcome to connect us,your first input is your name:\0";
int wellcome_length = strlen(wellcome_str);
int conn_number=0;void *client_run(void *args)
{Client *client = (Client *)args;if (client->socket == INVALID_SOCKET){printf("accept error !");closesocket(client->socket);}send(client->socket, wellcome_str, wellcome_length, 0);printf("新线程处理连接\n");//将接收第一条数据作为名字char name[1024];int ret = recv(client->socket, name, 1023, 0);if (ret > 0){client->name = name;name[ret] = 0x00;//添加结束符}char recvData[1024];char *sendData = (char *)malloc(1024 * sizeof(char));while (1){int ret = recv(client->socket, recvData, 1023, 0);//监听消息if (ret < 0)break;//断开连接memset(sendData, 0, 1024);recvData[ret] = 0x00;//添加结束符sprintf(sendData, "%s%s", client->name, fenge);//拼接字符串sprintf(sendData, "%s%s", sendData, recvData);//拼接字符串for (auto iter = clients.begin(); iter != clients.end(); ++iter) {//群发if (iter->first == client->id)continue;send(iter->second.socket, sendData, strlen(sendData), 0);}}clients.erase(client->id);conn_number--;closesocket(client->socket);printf("一个连接断开线程执行完毕\n");return NULL;
}void findIP(char *ip, int size)
{WORD v = MAKEWORD(1, 1);WSADATA wsaData;WSAStartup(v, &wsaData); // 加载套接字库struct hostent *phostinfo = gethostbyname("");char *p = inet_ntoa(*((struct in_addr *)(*phostinfo->h_addr_list)));strncpy(ip, p, size - 1);ip[size - 1] = '\0';WSACleanup();
}int main(int argc, char* argv[])
{//初始化WSAWORD sockVersion = MAKEWORD(2, 2);WSADATA wsaData;if (WSAStartup(sockVersion, &wsaData) != 0)return -1;//创建套接字SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//通信协议类型,数据类型,访问方式if (slisten == INVALID_SOCKET){printf("socket error !");WSACleanup();return -2;}printf("创建套接字成功!\n");char ip[20] = { 0 };findIP(ip, sizeof(ip));//绑定IP和端口sockaddr_in addr;addr.sin_family = AF_INET;//协议版本addr.sin_port = htons(8888);//addr.sin_addr.S_un.S_addr = inet_addr(ip);int r = bind(slisten, (LPSOCKADDR)&addr, sizeof(addr));if (r == SOCKET_ERROR){printf("bind error !");closesocket(slisten);return -3;}printf("绑定套接字成功!IP是:%s。\n",ip);if (listen(slisten, 10) == SOCKET_ERROR){printf("listen error !");return -4;}//循环接收连接int i = 0;//socket数组下标,自增IDClient *client;pthread_t *thread;SOCKADDR remote_addr;int remote_addr_rlen=sizeof(remote_addr);while (conn_number<=max_conn_number){client = (Client *)malloc(sizeof(Client));thread= (pthread_t *)malloc(sizeof(pthread_t));printf("等待连接...\n");client->socket = accept(slisten, &remote_addr, &remote_addr_rlen);//接收连接if (client->socket < 0){free(client);printf("接收失败\n");continue;}client->id = i;clients[i] = *client;//把连接存储在hash_mapprintf("接收到一个连接,开启新线程处理\n");conn_number++;pthread_create(thread, NULL, client_run, &clients[i]);i++;}closesocket(slisten);WSACleanup();return 0;
}

client代码:

#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>
#include<Windows.h>
#include<string.h>
#include<map>
#include<hash_map>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib, "pthreadVC2.lib")
void *receive_message(void *args)
{SOCKET *sClient = (SOCKET *)args;char *recvData = (char *)malloc(1024 * sizeof(char));recvData[1023]='\0';int ret;while(1){ret = recv(*sClient, recvData, 1023, 0);if (ret < 0)break;recvData[ret] = 0x00;//添加结束符printf("%s\n", recvData);}free(recvData);closesocket(*sClient);return NULL;
}int main(int argc, char* argv[])
{WORD sockVersion = MAKEWORD(2, 2);WSADATA wsaData;if (WSAStartup(sockVersion, &wsaData) != 0)return -1;printf("初始化WSA成功!\n");SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//通信协议类型,数据类型,访问方式if (sClient == INVALID_SOCKET){printf("socket error !");WSACleanup();return -2;}char server_ip[20] = { 0 };printf("创建套接字成功!请输入服务器IP:\n");scanf("%s", &server_ip);//获取服务器协议族sockaddr_in addr;addr.sin_family = AF_INET;//协议版本addr.sin_port = htons(8888);//addr.sin_addr.S_un.S_addr = inet_addr(server_ip);if (connect(sClient, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR){printf("connect error !");closesocket(sClient);return -3;}printf("连接服务器(%s)成功!\n",server_ip);pthread_t thread;pthread_create(&thread, NULL, receive_message, (void *)&sClient);//开启新线程,接收服务器发送的消息char *sendData = (char *)malloc(1024 * sizeof(char));;sendData[1023] = '\0';while (true){memset(sendData, 0, 1024);scanf("%s", sendData);if (sendData == "quit\0")break;send(sClient, sendData, strlen(sendData), NULL);}free(sendData);closesocket(sClient);WSACleanup();return 0;
}

C语言多人聊天室,Socket网络编程相关推荐

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

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

  2. linux多人聊天室 qt,Qt编程详解--网络通信之基于TCP的多人聊天室

    一.了解TCP的通信过程 Qt中封装了TCP协议 QTcpServer类负责服务端: 1.创建QTcpServer对象 2.监听listen需要的参数是地址和端口号 3.当有新的客户端连接成功时会发射 ...

  3. python实现udp聊天室_python网络编程基础--socket的简介,以及使用socket来搭建一个简单的udp小程序...

    socket介绍: socket(简称套接字),是进程间通讯的一个工具,他能实现把数据从一方传输到另一方,完成不同电脑上进程之间的通讯,它好比数据的搬运工. socket应用: 不夸张来说,只要跟网络 ...

  4. java多人聊天室与网络画板

    本篇主要是对本人前一篇通信博客在部分功能和代码结构上的优化,以下为前篇博客的地址: java通信-网络聊天室&网络画板(简陋版) 一.代码结构上的优化: 对前篇博客服务器类中最后流的关闭上代码 ...

  5. python实现多人聊天论文_python网络编程 双人多人聊天

    在学习网路编程时,我们首先要考虑的是其中的逻辑,我们借助打电话的形式来了解网络编程的过程, 我们打电话时属于呼叫方,接电话的属于被呼叫方,那么被呼叫方一直保持在待机状态,等待主呼叫方 呼叫,只有在被呼 ...

  6. C语言实现网络聊天室 socket的简单应用

    C语言实现网络聊天室 socket的简单应用 前言:环境是Linux ,使用了 socket和pthread,主要分为服务器端和客户端两部分,服务器端监听端口发来的请求,收到后向客户端发送一个消息,客 ...

  7. socket多人聊天室c语言,一分钟实现网页多人聊天室【Socket.IO】

    socket.io是个基于node.js的快平台实时通讯框架.只用不到10行代码,就可以搭建一个简单的多人实时聊天室. 先来看看运行后的效果: socket.io多人聊天室 只要简单几步,就可以实现. ...

  8. Python实现网络多人聊天室

    网络多人聊天室 相关连接:Python实现网络图形化界面多人聊天室 文件结构: chatroom ├── client.py  # 客户端代码 ├── language.py  # 语言文件 ├── ...

  9. java 网络编程 聊天_Java——网络编程(实现基于命令行的多人聊天室)

    目录: 1.ISO和TCP/IP分层模型 2.IP协议 3.TCP/UDP协议 4.基于TCP的网络编程 5.基于UDP的网络编程 6.基于TCP的多线程的聊天室的实现 1.ISO和TCP/IP分层模 ...

最新文章

  1. 【Qt】QStackedWidget:将多个窗口控件放入堆中,每次只显示一个窗口控件
  2. python爬虫好学不_Python爬虫好学吗?
  3. 编写windows 控件需要注意的几个标签属性(Attribute)
  4. 非科班通过几个月的培训入行人工智能现实吗?
  5. 计算机网络面试题整理
  6. Apache URLRewrite 原理及配置实现
  7. js 随机1-10随机数_寻找随机的错误-一个真实的故事
  8. homebrew 安装 formula 的不同历史版本——以安装 node 为例
  9. Flex 页面跳转 四种方法
  10. Enterprise Architect 8.0 注册码及其使用教程
  11. 收到阿里年终奖后,我感觉穷的睡不着,网友:贫穷限制了我的想象力
  12. Atitit 团队工具链体系打造---开发方面提升效率的软件与技术体系 attilax总结.docx
  13. rootkit后门检测工具rkhunter
  14. 服务器虚拟机解锁苹果,Unlocker(VMware虚拟机MacOS系统解锁工具)v3.0.2 免费版-ucbug软件站...
  15. FW软件的安装及简单的使用;
  16. 安装kali 不再难
  17. C++并发编程 - 同步并发操作
  18. linux命令行测试上网,如何使用linux命令行来测试网速
  19. 448. Find All Numbers Disappeared in an Array
  20. 计算机网络安全技术学习总结

热门文章

  1. Unicode,UTF-8编码,汉字编码
  2. 常用linux环境配置大全
  3. Spring Boot如何使用Redis进行API防刷限流?
  4. 计算机网络技术需要打字快,为啥有人打字非常非常快?我练了十来年还是一 – 手机爱问...
  5. mysql数据库导出select数据到excel打开发现身份证后几位变成0解决办法
  6. 好用的图片转换器:SizeMyPics for Mac
  7. 触发器(数据库必学)
  8. 天龙八部TLBB从0到1搭建教程-上
  9. 用Android代码实现自动打开USB调试
  10. ajax获取后台数据的几种方式及如何获取ajax内部的数据供外部使用