C++ Socket 一个服务器 多个客户端 (阻塞式)
来源:互联网 发布:matlab矩阵做聚类分析 编辑:程序博客网 时间:2024/04/25 21:10
服务端
ServerNet.h
#pragma once#include <stdio.h>#include <winsock.h>#include<vector>#include<iterator>#include<iostream>#include <algorithm>#include<map>#include<string>using namespace std;#pragma comment (lib,"ws2_32.lib")SOCKET sockConn;HANDLE bufferMutex; // 令其能互斥成功正常通信的信号量句柄 vector<SOCKET> clientSocketGroup; DWORD WINAPI WaitAcceptThread(LPVOID IpParameter);DWORD WINAPI RecMsgThread(LPVOID IpParameter);DWORD WINAPI SendMsgThread(LPVOID IpParameter);map<SOCKET,string> m_ipSocket;class CServerNet{private: SOCKET m_sock;public: CServerNet(void); //初始化服务器,返回0表示成功 int Init(const char* address,int port); //更新数据 void Run(); ~CServerNet(void);};
ServerNet.cpp
#include "ServerNet.h"int CServerNet::Init( const char* address,int port ){ int rlt = 0; //用于记录错误信息,并输出 int iErrorMsg; //初始化WinSock WSAData wsaData; iErrorMsg = WSAStartup(MAKEWORD(1,1),&wsaData); if (iErrorMsg != NO_ERROR) { //初始化WinSock失败 printf("wsastartup failed with error : %d\n",iErrorMsg); //WSAGetLastError() rlt = 1; return rlt; } //创建服务端Socket m_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (m_sock == INVALID_SOCKET) { //创建Socket异常 printf("socket failed with error : %d\n",WSAGetLastError()); rlt = 2; return rlt; } //声明信息 sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = port; serverAddr.sin_addr.s_addr = inet_addr(address); //绑定 iErrorMsg = bind(m_sock,(sockaddr*)&serverAddr,sizeof(serverAddr)); if (iErrorMsg < 0) { //绑定失败 printf("bind failed with error : %d\n",iErrorMsg); rlt = 3; return rlt; } return rlt;}void CServerNet::Run(){ //公开连接 listen(m_sock,20); int len = sizeof(sockaddr); bufferMutex = CreateSemaphore(NULL, 1, 1, NULL); //HANDLE sendThread = CreateThread(NULL,0,) HANDLE acceptThread = CreateThread(NULL, 0, WaitAcceptThread, (LPVOID)m_sock, 0, NULL); //do //{ // //接收信息 // newSocket = accept(m_sock,(sockaddr*)&tcpAddr,&len); // // if (newSocket == INVALID_SOCKET) // { // //非可用socket // } // else // { // //新socket连接 // printf("new socket connect : %d\n",newSocket); // //消息处理 // do // { // printf("process\n"); // //接收数据 // memset(buf,0,sizeof(buf)); // rval = recv(newSocket,buf,1024,0); // // if (rval == SOCKET_ERROR) // { // //这应该是个异常,当客户端没有调用closeSocket就直接退出游戏的时候,将会进入这里 // printf("recv socket error\n"); // break; // } // // // if (rval == 0) // //recv返回0表示正常退出 // printf("ending connection"); // else // //显示接收到的数据 // printf("recv %s\n",buf); // }while(rval != 0); // //关闭对应Accept的socket // closesocket(newSocket); // } // // //} while (1); //关闭自身的Socket WaitForSingleObject(acceptThread, INFINITE); // 等待线程结束 //WaitForSingleObject(sendThread, INFINITE); // 等待线程结束 //CloseHandle(sendThread); CloseHandle(bufferMutex); WSACleanup(); // 终止对套接字库的使用 closesocket(m_sock);}CServerNet::CServerNet(void){}CServerNet::~CServerNet(void){}DWORD WINAPI WaitAcceptThread(LPVOID IpParameter){ SOCKET m_socket = (SOCKET)IpParameter; while(true) { sockaddr_in tcpAddr; int len = sizeof(sockaddr_in); sockConn = accept(m_socket, (sockaddr*)&tcpAddr, &len); char t[20]; printf("%s:%d上线",inet_ntoa(tcpAddr.sin_addr),tcpAddr.sin_port); sprintf(t,"%s:%d",inet_ntoa(tcpAddr.sin_addr),tcpAddr.sin_port); string t1=t; if (SOCKET_ERROR != sockConn) { clientSocketGroup.push_back(sockConn); m_ipSocket[sockConn] = t1; } HANDLE receiveThread = CreateThread(NULL, 0, RecMsgThread, (LPVOID)sockConn, 0, NULL); WaitForSingleObject(bufferMutex, INFINITE); // P(资源未被占用) if(NULL == receiveThread) { printf("\nCreatThread AnswerThread() failed.\n"); } else{ printf("\nCreate Receive Client Thread OK.\n"); } ReleaseSemaphore(bufferMutex, 1, NULL); }}DWORD WINAPI RecMsgThread(LPVOID IpParameter){ SOCKET ClientSocket=(SOCKET)(LPVOID)IpParameter; int rval; while(1) { char recvBuf[1024]; rval = recv(ClientSocket, recvBuf, 1024, 0); WaitForSingleObject(bufferMutex, INFINITE); if (rval == SOCKET_ERROR) { printf("ONE Client Exit\n"); vector<SOCKET>::iterator result = find(clientSocketGroup.begin(), clientSocketGroup.end(), ClientSocket); clientSocketGroup.erase(result); for (map<SOCKET, string>::iterator i=m_ipSocket.begin(); i!=m_ipSocket.end(); i++) { if (i->first == ClientSocket) { printf("%s下线\n",m_ipSocket[ClientSocket].c_str()); m_ipSocket.erase(i); break; } } closesocket(ClientSocket); ReleaseSemaphore(bufferMutex, 1, NULL); break; } printf("%s Says: %s\n", m_ipSocket[ClientSocket].c_str(), recvBuf); // 接收信息 ReleaseSemaphore(bufferMutex, 1, NULL); } return 0;}int main(){ CServerNet serverNet; int iRlt = serverNet.Init("127.0.0.1",8888); if (iRlt == 0) { printf("init ok...\n"); serverNet.Run(); } else printf("serverNet init failed with error : %d\n",iRlt); system("pause"); return 0;}
客户端
ClientNet.h
#pragma once#include<stdio.h>#include<Windows.h>#pragma comment(lib, "Ws2_32.lib")class CClientNet{private: SOCKET m_sock;public: CClientNet(void); //连接上指定服务器 int Connect(int port,const char* address); //发送信息 int SendMsg(const char* msg,int len); //关闭 void Close(); ~CClientNet(void);};
ServerNet.cpp
#include "ServerNet.h"int CServerNet::Init( const char* address,int port ){ int rlt = 0; //用于记录错误信息,并输出 int iErrorMsg; //初始化WinSock WSAData wsaData; iErrorMsg = WSAStartup(MAKEWORD(1,1),&wsaData); if (iErrorMsg != NO_ERROR) { //初始化WinSock失败 printf("wsastartup failed with error : %d\n",iErrorMsg); //WSAGetLastError() rlt = 1; return rlt; } //创建服务端Socket m_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (m_sock == INVALID_SOCKET) { //创建Socket异常 printf("socket failed with error : %d\n",WSAGetLastError()); rlt = 2; return rlt; } //声明信息 sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = port; serverAddr.sin_addr.s_addr = inet_addr(address); //绑定 iErrorMsg = bind(m_sock,(sockaddr*)&serverAddr,sizeof(serverAddr)); if (iErrorMsg < 0) { //绑定失败 printf("bind failed with error : %d\n",iErrorMsg); rlt = 3; return rlt; } return rlt;}void CServerNet::Run(){ //公开连接 listen(m_sock,20); int len = sizeof(sockaddr); bufferMutex = CreateSemaphore(NULL, 1, 1, NULL); //HANDLE sendThread = CreateThread(NULL,0,) HANDLE acceptThread = CreateThread(NULL, 0, WaitAcceptThread, (LPVOID)m_sock, 0, NULL); //do //{ // //接收信息 // newSocket = accept(m_sock,(sockaddr*)&tcpAddr,&len); // // if (newSocket == INVALID_SOCKET) // { // //非可用socket // } // else // { // //新socket连接 // printf("new socket connect : %d\n",newSocket); // //消息处理 // do // { // printf("process\n"); // //接收数据 // memset(buf,0,sizeof(buf)); // rval = recv(newSocket,buf,1024,0); // // if (rval == SOCKET_ERROR) // { // //这应该是个异常,当客户端没有调用closeSocket就直接退出游戏的时候,将会进入这里 // printf("recv socket error\n"); // break; // } // // // if (rval == 0) // //recv返回0表示正常退出 // printf("ending connection"); // else // //显示接收到的数据 // printf("recv %s\n",buf); // }while(rval != 0); // //关闭对应Accept的socket // closesocket(newSocket); // } // // //} while (1); //关闭自身的Socket WaitForSingleObject(acceptThread, INFINITE); // 等待线程结束 //WaitForSingleObject(sendThread, INFINITE); // 等待线程结束 //CloseHandle(sendThread); CloseHandle(bufferMutex); WSACleanup(); // 终止对套接字库的使用 closesocket(m_sock);}CServerNet::CServerNet(void){}CServerNet::~CServerNet(void){}DWORD WINAPI WaitAcceptThread(LPVOID IpParameter){ SOCKET m_socket = (SOCKET)IpParameter; while(true) { sockaddr_in tcpAddr; int len = sizeof(sockaddr_in); sockConn = accept(m_socket, (sockaddr*)&tcpAddr, &len); char t[20]; printf("%s:%d上线",inet_ntoa(tcpAddr.sin_addr),tcpAddr.sin_port); sprintf(t,"%s:%d",inet_ntoa(tcpAddr.sin_addr),tcpAddr.sin_port); string t1=t; if (SOCKET_ERROR != sockConn) { clientSocketGroup.push_back(sockConn); m_ipSocket[sockConn] = t1; } HANDLE receiveThread = CreateThread(NULL, 0, RecMsgThread, (LPVOID)sockConn, 0, NULL); WaitForSingleObject(bufferMutex, INFINITE); // P(资源未被占用) if(NULL == receiveThread) { printf("\nCreatThread AnswerThread() failed.\n"); } else{ printf("\nCreate Receive Client Thread OK.\n"); } ReleaseSemaphore(bufferMutex, 1, NULL); }}DWORD WINAPI RecMsgThread(LPVOID IpParameter){ SOCKET ClientSocket=(SOCKET)(LPVOID)IpParameter; int rval; while(1) { char recvBuf[1024]; rval = recv(ClientSocket, recvBuf, 1024, 0); WaitForSingleObject(bufferMutex, INFINITE); if (rval == SOCKET_ERROR) { printf("ONE Client Exit\n"); vector<SOCKET>::iterator result = find(clientSocketGroup.begin(), clientSocketGroup.end(), ClientSocket); clientSocketGroup.erase(result); for (map<SOCKET, string>::iterator i=m_ipSocket.begin(); i!=m_ipSocket.end(); i++) { if (i->first == ClientSocket) { printf("%s下线\n",m_ipSocket[ClientSocket].c_str()); m_ipSocket.erase(i); break; } } closesocket(ClientSocket); ReleaseSemaphore(bufferMutex, 1, NULL); break; } printf("%s Says: %s\n", m_ipSocket[ClientSocket].c_str(), recvBuf); // 接收信息 ReleaseSemaphore(bufferMutex, 1, NULL); } return 0;}int main(){ CServerNet serverNet; int iRlt = serverNet.Init("127.0.0.1",8888); if (iRlt == 0) { printf("init ok...\n"); serverNet.Run(); } else printf("serverNet init failed with error : %d\n",iRlt); system("pause"); return 0;}
0 0
- C++ Socket 一个服务器 多个客户端 (阻塞式)
- 非阻塞socket对应的多线程服务器的实现---一个服务器如何与多个客户端进行通信?
- Socket 编程,一个服务器,多个客户端,互相通信(分享)
- Socket 编程,一个服务器,多个客户端,互相通信
- socket实现多个客户端连接在一个服务器上
- Socket编程,一个服务器与多个客户端
- socket编程补充---一个服务器多个客户端
- java Socket 一个服务器与多个客户端进行通信
- Socket 编程,一个服务器,多个客户端,互相通信
- Socket编程服务器和客户端(多个客户端可以同时连接一个服务器的同一端口)
- Socket编程服务器和客户端(多个客户端可以同时连接一个服务器的同一端口)
- Socket编程服务器和客户端(多个客户端可以同时连接一个服务器的同一端口)
- Socket编程总结—Android手机服务器与多个Android手机客户端之间的通信(非阻塞)
- Socket编程总结—Android手机服务器与多个Android手机客户端之间的通信(非阻塞)
- Socket编程总结—Android手机服务器与多个Android手机客户端之间的通信(非阻塞)
- java Socket--tcp 一个服务器多客户端
- C# Socket聊天程序(一个服务端,多个客户端)
- C# Socket聊天程序(一个服务端,多个客户端)
- 144. Binary Tree Preorder Traversal
- mysqli连接数据库
- 2016/08/11 多态
- HDU1542 线段树+离散化+扫描线
- ArrayList的使用方法
- C++ Socket 一个服务器 多个客户端 (阻塞式)
- 3000门徒内部训练绝密视频(泄密版)第6课:精通Spark集群搭建与测试
- 钱仓【NOIP2016提高A组8.11】
- 微信支付H5调用支付详解
- JAVA中list,set,数组之间的转换详解
- Handler机制原理
- Jmeter3.0 Body Data 中文参数显示乱码的解决方式。
- git常用命令
- 数组中只出现一次的数字