linux c++ 简易聊天室
来源:互联网 发布:美业邦软件的弊端 编辑:程序博客网 时间:2024/06/05 03:29
c++聊天室编程记录(Linux环境基于eclipse c++)
server类
server.h
#ifndef SERVER_SERVER_H_#define SERVER_SERVER_H_#include <iostream>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <arpa/inet.h>#include <time.h>#include <list>#include <errno.h>#include <pthread.h>#include <sstream>using namespace std;void* handClient(void* arg);void* announce(void* arg);class Server {public: Server(const int& port); ~Server();public: void run(); friend void* handClient(void*);private: void forwardMsg(const char* msg, size_t length);private: int port; int serverSock; list<int>* clientsP;};static pthread_mutex_t printLocker = PTHREAD_MUTEX_INITIALIZER;static pthread_mutex_t clientsLocker = PTHREAD_MUTEX_INITIALIZER;struct ThdArg{ int sockClient; sockaddr_in addr; void* mainObj;};#endif /* SERVER_SERVER_H_ */
server.cpp
#include "Server.h"Server::Server(const int& port) { this->port = port; this->clientsP = new list<int>;}Server::~Server() { delete clientsP;}void Server::run() { sockaddr_in addr; if ((serverSock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0) { cout << "create socket error" << endl; exit(-1); } int opt = SO_REUSEADDR; setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if (bind(serverSock, (sockaddr*) &addr, sizeof(addr)) < 0) { cout << "bind error" << endl; exit(-1); } if (listen(serverSock, 50) < 0) { cout << "listen error" << endl; exit(-1); } cout << "server now is running, wait client to connect" << endl; unsigned int addrLen = sizeof(sockaddr_in); pthread_attr_t attr; pthread_t tid; while (true) { ThdArg* arg = new ThdArg; arg->mainObj = this; arg->sockClient = accept(serverSock, (sockaddr*) &(arg->addr), &addrLen); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (pthread_create(&tid, &attr, handClient, arg) < 0) { cout << "create thread error" << endl; } pthread_attr_destroy(&attr); }}void* handClient(void* arg) { ThdArg* para = (ThdArg*) arg; int clientSock = para->sockClient; sockaddr_in addr = para->addr; Server* serverP = (Server*) (para->mainObj); ostringstream portStr; portStr << addr.sin_port; pthread_mutex_lock(&clientsLocker); serverP->clientsP->push_back(clientSock); pthread_mutex_unlock(&clientsLocker); string hello(inet_ntoa(addr.sin_addr)); hello += ":"; hello += portStr.str(); hello += " join room\n"; serverP->forwardMsg(&hello[0], hello.length()); pthread_mutex_lock(&printLocker); cout << hello; pthread_mutex_unlock(&printLocker); int ret; fd_set set; timeval tv = { 1, 0 }; char recvBuff[1024]; string msg; while (true) { FD_ZERO(&set); FD_SET(clientSock, &set); ret = select(clientSock + 1, &set, NULL, NULL, &tv); if (ret <= 0) { continue; } else if (FD_ISSET(clientSock, &set)) { ret = recv(clientSock, recvBuff, sizeof(recvBuff), 0); if (ret <= 0) { if (errno == EINTR) continue; else break; } recvBuff[ret] = 0; msg = inet_ntoa(addr.sin_addr); msg += ":"; msg += (portStr.str()+":"); msg += recvBuff; pthread_mutex_lock(&printLocker); cout << recvBuff << endl; pthread_mutex_unlock(&printLocker); serverP->forwardMsg(&msg[0], msg.length()); } } string levMsg = (inet_ntoa(addr.sin_addr)); levMsg += ":"; levMsg += portStr.str(); levMsg += " disconnected\n"; serverP->forwardMsg(&levMsg[0], levMsg.length()); pthread_mutex_lock(&printLocker); cout << levMsg; pthread_mutex_unlock(&printLocker); close(clientSock); pthread_mutex_lock(&clientsLocker); serverP->clientsP->remove(clientSock); pthread_mutex_unlock(&clientsLocker); delete para; return 0;}void Server::forwardMsg(const char* msg, size_t length) { char sendBuff[length]; strcpy(sendBuff, msg); pthread_mutex_lock(&clientsLocker); for(list<int>::iterator begin = clientsP->begin(); begin != clientsP->end(); ++begin){ if(send(*begin, sendBuff, length, 0) < 0){ pthread_mutex_lock(&printLocker); cout << "one send error"<<endl; pthread_mutex_unlock(&printLocker); } } pthread_mutex_unlock(&clientsLocker);}
main.cpp
#include "server/Server.h"int main(){ Server server(6666); server.run(); return 0;}
Client类
client.h
#ifndef CLIENT_CLIENT_H_#define CLIENT_CLIENT_H_#include <iostream>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#include <arpa/inet.h>#include <time.h>#include <errno.h>#include <pthread.h>using namespace std;void* recvMsg(void* arg);class Client {public: Client(const char* serverIp, const int& port); ~Client();public: void run(); friend void* recvMsg(void* arg);private: int sockClient; char* serverIp; int port;};#endif /* CLIENT_CLIENT_H_ */
client.cpp
#include "Client.h"Client::Client(const char* serverIp, const int& port) { this->serverIp = (char*) serverIp; this->port = port;}Client::~Client() {}void Client::run() { sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(serverIp); addr.sin_port = htons(port); sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (connect(sockClient, (sockaddr*) &addr, sizeof(addr)) < 0) { cout << "connect error" << endl; exit(-1); } cout << "connect server success" << endl; pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); int ret = pthread_create(&tid, &attr, recvMsg, this); if (ret < 0) { cout << "create thread error" << endl; } pthread_attr_destroy(&attr); string msg; while (true) { cin >> msg; send(sockClient, &msg[0], msg.length(), 0); } close(sockClient);}void* recvMsg(void* arg) { Client* clientP = (Client*)arg; int sock = clientP->sockClient; char recvBuff[1024]; int ret; fd_set set; timeval tv = { 1, 0 }; while (true) { FD_ZERO(&set); FD_SET(sock, &set); ret = select(sock + 1, &set, NULL, NULL, &tv); if (ret <= 0){ continue; } else if (FD_ISSET(sock, &set)) { ret = recv(sock, recvBuff, sizeof(recvBuff), 0); if (ret <= 0) { if (errno == EINTR){ continue; } else{ cout<<"you have been disconnected"<<endl; break; } } recvBuff[ret] = 0; cout << recvBuff << endl; } } close(sock); return 0;}
main.cpp
#include "client/Client.h"int main(){ Client client("127.0.0.1", 6666); client.run(); return 0;}
运行
发送消息可能有些小bug
自学c++可能有许多漏洞或者不恰当的地方望见谅,以上需要配置多线程环境,eclipse->project->properties->c/c++ build->settings->gcc c++ linker ->libraries(-l)添加pthread库
阅读全文
1 0
- linux C简易版聊天室(一)
- linux C简易版聊天室(二)
- linux c++ 简易聊天室
- 简易命令行界面的C/S聊天室
- 基于Linux c 用socket和线程 实现的简易聊天室之服务器
- 基于Linux C 用socket和线程 实现的简易聊天室之客户端
- Linux c语言 聊天室
- 简易聊天室
- Java 简易C/S结构多线程聊天室 (阻塞式)
- C 基于UDP实现一个简易的聊天室
- linux下使用UDP实现简易的多人聊天室
- 简易聊天室的制作
- 简易局域网聊天室程序
- Java简易聊天室
- 简易多人聊天室
- socket简易聊天室
- ASP.net--简易聊天室
- Websocket学习--简易聊天室
- Tomcat MemoryLeak 问题
- 118. Pascal's Triangle
- Spring Boot 日志配置(超详细)
- Opencv 中cv开头的函数和没有cv的区别,例如cvWaitkey()和waitKey()的区别
- 自定义控件之自定义xmlns
- linux c++ 简易聊天室
- springmvc从数据库中读取数据并且显示成选择框
- Crontab 使用说明
- mysql5.7设置密码安全级别 ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
- 遥感影像镶嵌软件功能介绍
- PyQt5中文基础教程12 俄罗斯方块游戏
- TCP/IP学习笔记(一)基础知识
- 原型模式
- hdu 2586 How far away? 【LCA】 解题报告