Search Unity

Creating my own server-client using C++

Discussion in 'Multiplayer' started by Durins-Bane, Apr 5, 2016.

  1. Durins-Bane

    Durins-Bane

    Joined:
    Sep 21, 2012
    Posts:
    175
    Hello all :)
    I just started looking more into multiplayer games and want to make my own server if possible purely so I can learn what makes them work.

    I found this http://www.codeproject.com/Articles/412511/Simple-client-server-network-using-Cplusplus-and-W
    which I have now setup and have working. My question is how could I set this up to work with my game in unity.
    How would I connect as a client, should I use a separate launcher like WoW to get all the players info and have that running?
    How can I send packets from within unity to the master server and then send them back. Far as I cant tell the server from the site has everything id need but I dont quite understand it, could anyone go into further detail about what is happening?

    Thank you :)
     
  2. Durins-Bane

    Durins-Bane

    Joined:
    Sep 21, 2012
    Posts:
    175
  3. Hayz0rx

    Hayz0rx

    Joined:
    Apr 2, 2016
    Posts:
    34
    What does your send function look like? Are you using WriteLine() or something in C# to write data into the stream?
    If yes, you should know that it appends "\n" at the end of your data, this is pretty useless if you are using the receive method on C++. You should only do your Login- and Gameserver in C++ (or an extern C# app) and the Worldserver in Unity. You will need the map data and physics engine in order to make world sanity checks etc.
     
  4. Durins-Bane

    Durins-Bane

    Joined:
    Sep 21, 2012
    Posts:
    175
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4. using System.IO;
    5. using System.Net.Sockets;
    6.  
    7. public class TCPConnection : MonoBehaviour {
    8.  
    9.     //the name of the connection, not required but better for overview if you have more than 1 connections running
    10.     public string conName = "Localhost";
    11.  
    12.     //ip/address of the server, 127.0.0.1 is for your own computer
    13.     public string conHost = "127.0.0.1";
    14.  
    15.     //port for the server, make sure to unblock this in your router firewall if you want to allow external connections
    16.     public int conPort = 6881;
    17.  
    18.     //a true/false variable for connection status
    19.     public bool socketReady = false;
    20.  
    21.     TcpClient mySocket;
    22.     NetworkStream theStream;
    23.     StreamWriter theWriter;
    24.     StreamReader theReader;
    25.  
    26. //try to initiate connection
    27.   public void setupSocket() {
    28.         try {
    29.             mySocket = new TcpClient(conHost, conPort);
    30.             theStream = mySocket.GetStream();
    31.             theWriter = new StreamWriter(theStream);
    32.             theReader = new StreamReader(theStream);
    33.             socketReady = true;
    34.         }
    35.         catch (Exception e) {
    36.             Debug.Log("Socket error:" + e);
    37.         }
    38.     }
    39.  
    40.     //send message to server
    41.     public void writeSocket(string theLine) {
    42.         if (!socketReady)
    43.             return;
    44.         String tmpString = theLine + "\n";
    45.         theWriter.Write(tmpString);
    46.         theWriter.Flush();
    47.     }
    48.  
    49.     //read message from server
    50.     public string readSocket() {
    51.         String result = "";
    52.         if (theStream != null) {  
    53.             if (theStream.DataAvailable) {
    54.                 Byte[] inStream = new Byte[mySocket.SendBufferSize];
    55.                 theStream.Read (inStream, 0, inStream.Length);
    56.                 result += System.Text.Encoding.UTF8.GetString (inStream);
    57.             }
    58.         }
    59.         return result;
    60.     }
    61.  
    62.     //disconnect from the socket
    63.     public void closeSocket() {
    64.         if (!socketReady)
    65.             return;
    66.         theWriter.Close();
    67.         theReader.Close();
    68.         mySocket.Close();
    69.         socketReady = false;
    70.     }
    71.  
    72.     //keep connection alive, reconnect if connection lost
    73.     public void maintainConnection(){
    74.         if(!theStream.CanRead) {
    75.             setupSocket();
    76.         }
    77.     }
    78.  
    79.  
    80. }
    81.  

    This is what my receive looks like
    Code (CSharp):
    1. void ServerGame::receiveFromClients()
    2. {
    3.     Packet packet;
    4.     // go through all clients
    5.     std::map<unsigned int, SOCKET>::iterator iter;
    6.  
    7.     for(iter = network->sessions.begin(); iter != network->sessions.end(); iter++)    {
    8.         int data_length = network->receiveData(iter->first, network_data);
    9.         if (data_length <= 0) {
    10.             //no data recieved
    11.             continue; }
    12.  
    13.         int i = 0;
    14.         while (i < (unsigned int)data_length  {
    15.             packet.deserialize(&(network_data[i]));
    16.             i += sizeof(Packet);
    17.             switch (packet.packet_type) {
    18.                 case INIT_CONNECTION:
    19.                     printf("server received init packet from client\n");
    20.                     sendActionPackets();
    21.                     break;
    22.  
    23.                 case ACTION_EVENT:
    24.                   //  printf("server received action event packet from client\n");
    25.                     sendActionPackets();
    26.                     break;
    27.  
    28.                 default:
    29.  
    30.                         printf("error in packet types\n");
    31.                     break;
    32.            }    }   }
    33. }

    I can send packets to the server and the client receives them Its just that when I send one from in game using the script above I get an error on the server which says error in packet type or something similar.

    How can I setup this in Unity C#?

    Code (CSharp):
    1. void ClientGame::sendActionPackets()
    2. {
    3.     // send action packet
    4.     const unsigned int packet_size = sizeof(Packet);
    5.     char packet_data[packet_size];
    6.  
    7.     Packet packet;
    8.     packet.packet_type = ACTION_EVENT;
    9.  
    10.     packet.serialize(packet_data);
    11.  
    12.     NetworkServices::sendMessage(network->ConnectSocket, packet_data, packet_size);
    13. }
    I found this in NetworkData.h where the packet is declared.
    Would I have to add this in C# to my script that sends packets to the server?
    Code (CSharp):
    1. #pragma once
    2. #include <string.h>
    3.  
    4. #define MAX_PACKET_SIZE 1000000
    5.  
    6. enum PacketTypes {
    7.  
    8.     INIT_CONNECTION = 0,
    9.  
    10.     ACTION_EVENT = 1,
    11.  
    12. };
    13.  
    14. struct Packet {
    15.  
    16.     unsigned int packet_type;
    17.  
    18.     void serialize(char * data) {
    19.         memcpy(data, this, sizeof(Packet));
    20.     }
    21.  
    22.     void deserialize(char * data) {
    23.         memcpy(this, data, sizeof(Packet));
    24.     }
    25. };
     
  5. Hayz0rx

    Hayz0rx

    Joined:
    Apr 2, 2016
    Posts:
    34
    You should stop C&P and read about using sockets or streams in C# and using winsock2 in C++.
     
  6. Durins-Bane

    Durins-Bane

    Joined:
    Sep 21, 2012
    Posts:
    175
    These are literally the first things I have come across, I didn't have a clue where to start so just started looking for some code till found something that worked and was going try work it out from there.

    Will look into streams and winsock now :)