服务端部分

来源:互联网 发布:淘宝店铺交易数据分析 编辑:程序博客网 时间: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();}}





原创粉丝点击