I am currently working on a Udp server and client system, where I worked out a way to "verify" which user is sending the updates. Essentially, the very first package they send is "blank", which the server takes in, increments a list by 1, and then does a Send()
to the port, which I believe should go to all connected Clients (please correct me if I'm wrong on this assumption). The client will ignore any new "ID's" that are coming in after theirs is assigned, and the ID part of the server will ignore any packages that don't start with a blank space.
My current issue is:
I can't seem to get more than one client connected, and I'm a little stumped on why.
Server/Client Manager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
public class ServerManager : MonoBehaviour
{
private GameObject serverGO;
private Thread serverThread;
private Thread clientThread;
private Server1 serverScript;
private Client1 clientScript;
private bool serverThreadRunning = false;
private bool clientThreadRunning = false;
// Start is called before the first frame update
void Start()
{
serverGO = this.gameObject;
serverScript = new Server1();
clientScript = new Client1();
serverThread = new Thread(serverScript.Listen);
clientThread = new Thread(clientScript.SendData);
}
// Update is called once per frame
void Update()
{
Control();
Debug.Log(serverScript.GetClientID().Count);
Debug.Log(serverScript.GetContact());
}
private void OnApplicationQuit()
{
serverScript.done = true;
}
private void Control()
{
if (Input.GetKeyDown(KeyCode.P) && !(serverThreadRunning) && !(clientThreadRunning))
{
serverThreadRunning = true;
serverThread.Start();
}
else if (Input.GetKeyDown(KeyCode.L) && !(serverThreadRunning) && !(clientThreadRunning))
{
clientThreadRunning = true;
clientThread.Start();
}
if (Input.GetKeyDown(KeyCode.M) && clientThreadRunning)
{
clientScript.disconnect = true;
}
}
}
Server:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class Server1 : MonoBehaviour
{
private CancellationTokenSource cancellationSource = new CancellationTokenSource();
Dictionary<int, IPEndPoint> clientID = new Dictionary<int, IPEndPoint>();
private int done = 0;
public string rds;
public void Listen()
{
int port = 8080;
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ep = new IPEndPoint(IPAddress.Any, port);
UdpClient listener = new UdpClient(ep);
byte[] rData;
string rDataString;
byte[] sendData;
string sendDataString;
var token = cancellationSource.Token;
try
{
while (token.IsCancellationRequested)
{
var receiveTask = listener.ReceiveAsync();
var result = receiveTask.Result;
rData = result.Buffer;
rDataString = Encoding.ASCII.GetString(rData);
if (rDataString.Equals(" "))
{
var clientAddress = ep.Address;
ep = new IPEndPoint(clientAddress, port);
var id = (clientID.Count + 1);
sendDataString = id.ToString();
sendData = Encoding.ASCII.GetBytes(sendDataString);
clientID.Add(id, ep);
var clientEP = result.RemoteEndPoint;
serverSocket.SendTo(sendData, ep);
//serverSocket.Close();
}
else
{
rds = rDataString;
}
}
}
catch (Exception e)
{
Debug.Log("Server error: " + e.ToString());
}
listener.Close();
}
public Dictionary<int, IPEndPoint> GetClientID()
{
return clientID;
}
public string GetContact()
{
return rds;
}
public void Stop()
{
cancellationSource.Cancel();
}
}
Client:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System;
using System.Text;
public class Client1 : MonoBehaviour
{
private GameObject player;
private Transform playerPos;
public bool disconnect = false;
public bool requestClientId = false;
public void SendData()
{
Move updatePlayer = new Move();
GameObject player;
Transform playerPos;
Client1 parent = new Client1();
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
int port = 8080;
IPAddress ip = IPAddress.Parse("10.10.33.24");
IPEndPoint ipep = new IPEndPoint(ip, port);
bool disconnect = false;
byte[] sendData;
int clientID = -1;
byte[] rData;
string rDataString;
while (true)
{
if (parent.disconnect != disconnect)
{
disconnect = parent.disconnect;
}
try
{
if (clientID < 0)
{
sendData = Encoding.ASCII.GetBytes(" ");
clientSocket.SendTo(sendData, ipep);
UdpClient listener = new UdpClient(ipep);
rData = listener.Receive(ref ipep);
rDataString = Encoding.ASCII.GetString(rData);
clientID = Int32.Parse(rDataString);
listener.Close();
}
else if (clientID > 0)
{
sendData = Encoding.ASCII.GetBytes("didit");
clientSocket.SendTo(sendData, ipep);
}
}
catch (Exception e)
{
}
if (disconnect)
{
clientSocket.Close();
}
}
}
}
This is clearly an unfinished product, I am aware I'm missing some key future pieces (removing players from list, having the designated time for the server to do a listener.Close()
), but for now I'm just trying to get multiple clients connected at the same time, and am looking for a point in the right direction.
Edit:
Updated Server code