服务端部分
来源:互联网 发布:淘宝店铺交易数据分析 编辑:程序博客网 时间:2024/05/01 11:33
来自:http://www.codeproject.com/Articles/412511/Simple-client-server-network-using-Cplusplus-and-W
包含四个文件:
ServerNetwork.h //对服务端socket的初始化,数据收发
ServerNetwork.cpp
ServerGame.h //对数据收发的处理
ServerGame.cpp
#include <winsock2.h>#include <ws2tcpip.h>#include <map>using namespace std; #define DEFAULT_PORT "6881" class ServerNetwork{public: ServerNetwork(void); ~ServerNetwork(void);// send data to all clients void sendToAll(char * packets, int totalSize);// receive incoming data int receiveData(unsigned int client_id, char * recvbuf);// accept new connections bool acceptNewClient(unsigned int & id); // Socket to listen for new connections SOCKET ListenSocket; // Socket to give to the clients SOCKET ClientSocket; // table to keep track of each client's socket std::map<unsigned int, SOCKET> sessions; };
#include "StdAfx.h"#include "ServerNetwork.h"#include "NetworkServices.h"#include "NetworkData.h"ServerNetwork::ServerNetwork(void){int iResult;// create WSADATA object WSADATA wsaData; // our sockets for the server ListenSocket = INVALID_SOCKET; ClientSocket = INVALID_SOCKET; // address info for the server to listen to struct addrinfo *result = NULL; struct addrinfo hints; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); exit(1); } // set address information ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; // TCP connection!!! hints.ai_flags = AI_PASSIVE; // Resolve the server address and port iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if ( iResult != 0 ) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); exit(1); } // Create a SOCKET for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); exit(1); } // Set the mode of the socket to be nonblocking u_long iMode = 1; iResult = ioctlsocket(ListenSocket, FIONBIO, &iMode); if (iResult == SOCKET_ERROR) { printf("ioctlsocket failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); exit(1); } // Setup the TCP listening socket iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { printf("bind failed with error: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); exit(1); } // no longer need address information freeaddrinfo(result); // start listening for new clients attempting to connect iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { printf("listen failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); exit(1); }}ServerNetwork::~ServerNetwork(void){}// accept new connectionsbool ServerNetwork::acceptNewClient(unsigned int & id){ // if client waiting, accept the connection and save the socket ClientSocket = accept(ListenSocket,NULL,NULL); if (ClientSocket != INVALID_SOCKET) { //disable nagle on the client's socket char value = 1; setsockopt( ClientSocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof( value ) ); // insert new client into session id table sessions.insert( pair<unsigned int, SOCKET>(id, ClientSocket) ); return true; } return false;}// receive incoming dataint ServerNetwork::receiveData(unsigned int client_id, char * recvbuf){ if( sessions.find(client_id) != sessions.end() ) { SOCKET currentSocket = sessions[client_id];int iResult; iResult = NetworkServices::receiveMessage(currentSocket, recvbuf, MAX_PACKET_SIZE); if (iResult == 0) { printf("Connection closed\n"); closesocket(currentSocket); } return iResult; } return 0;}// send data to all clientsvoid ServerNetwork::sendToAll(char * packets, int totalSize){ SOCKET currentSocket; std::map<unsigned int, SOCKET>::const_iterator iter;int iResult; for (iter = sessions.begin(); iter != sessions.end(); ++iter) { currentSocket = iter->second; iResult = NetworkServices::sendMessage(currentSocket, packets, totalSize); if (iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(currentSocket); } }}
#include "ServerNetwork.h"#include "NetworkData.h"class ServerGame{public: ServerGame(void); ~ServerGame(void); void update();private:void receiveFromClients();void sendActionPackets(); // IDs for the clients connecting for table in ServerNetwork static unsigned int client_id; // The ServerNetwork object ServerNetwork* network;// data buffer char network_data[MAX_PACKET_SIZE];};
#include "StdAfx.h"#include "ServerGame.h"//注:static 默认为0unsigned int ServerGame::client_id; ServerGame::ServerGame(void){ // id's to assign clients for our table client_id = 0; // set up the server network to listen network = new ServerNetwork(); }ServerGame::~ServerGame(void){}void ServerGame::update(){ // get new clients if(network->acceptNewClient(client_id)) { printf("client %d has been connected to the server\n",client_id); client_id++; } receiveFromClients();}void ServerGame::receiveFromClients(){ Packet packet; // go through all clients std::map<unsigned int, SOCKET>::iterator iter; for(iter = network->sessions.begin(); iter != network->sessions.end(); iter++) { int data_length = network->receiveData(iter->first, network_data); if (data_length <= 0) { //no data recieved continue; } unsigned int i = 0; while (i < (unsigned int)data_length) { packet.deserialize(&(network_data[i])); i += sizeof(Packet); switch (packet.packet_type) { case INIT_CONNECTION: printf("server received init packet from client\n"); sendActionPackets(); break; case ACTION_EVENT: printf("server received action event packet from client\n"); sendActionPackets(); break; default: printf("error in packet types\n"); break; } } }}void ServerGame::sendActionPackets(){ // send action packet const unsigned int packet_size = sizeof(Packet); char packet_data[packet_size]; Packet packet; packet.packet_type = ACTION_EVENT; packet.serialize(packet_data); network->sendToAll(packet_data,packet_size);}
简单使用:
#include <process.h>void serverLoop(void *);ServerGame * server; int main(){// initialize the serverserver = new ServerGame();// create thread with arbitrary argument for the run function_beginthread( serverLoop, 0, (void*)12);}void serverLoop(void * arg) { while(true) {server->update();}}
- 服务端部分
- 客户端 服务端公共部分
- 服务端部分解决方案
- 任务系统之服务端部分
- CAS 服务端部署 部分配置
- NIO非阻塞通信服务端部分代码
- 2011金山软件-服务端开发工程师(JAVA)部分笔试题
- mqtt协议即时消息服务端接收的消息缺少部分字节
- 在Windows下配置svn服务端钩子程序(部分)
- 服务端
- 服务端
- 服务端
- 求救!小弟写了一个java的服务端部分,但是无法正常关闭。
- hbase 源代码解析(3) 的createTable 服务端解析第二部分
- 【转】RTSP协议源码,分服务与请求两部分。可以用于服务端服务和客户端请求
- 使用 Eclipse 和 Java SE 6 创建独立 Web Services 应用程序,第 1 部分: Web Services 服务端应用程序
- 使用 Eclipse 和 Java SE 6 创建独立 Web Services 应用程序,第 1 部分: Web Services 服务端应用程序
- HTTP服务端JSON服务端
- UVa 572Oil Deposits
- NYOJ网络的可靠性
- PHP学习系列之错误处理和异常捕获
- HDU1337(hash)
- ContentProvider内容提供者(一)
- 服务端部分
- Calculate Linux 13 Beta 1 发布
- sqlserver日历表
- UVa 10617 - Again Palindrome
- EDK10.1的ModelSim仿真库的生成
- 整型和字符串的相互转化
- js定时器
- java里测试时间代码
- C++ 构造函数