Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System;
- using System.Collections;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- public class accept_thread_check{ //class for the accept() threads (to avoid blocking)
- public bool done = false;
- public Socket connection;
- }
- public class holder{ //class for a socket and thread container, and to see if each connection is open
- public Socket[] s_holder;
- public Thread[] t_holder;
- public bool[] open_closed;
- }
- public class data_array{ //class to create jagged multi-type array for receiving and sending
- public Socket connection;
- public double[] data_double {get;set;}
- public double[] data_double_temp {get;set;}
- public byte[] data_byte {get;set;}
- //public byte[] data_byte_temp {get;set;} //not currently in use
- }
- public class Client : MonoBehaviour{
- int player_count = -1; //number of players. set by outside script before Start() is called
- //IPAddress[] ipaddrs; //currently no need to store the connected IP Adresses
- data_array[] data; //array of objects for the data_array class
- holder holder_obj = new holder(); //object for the holder_object class
- int holder_obj_index = 0; //reference to the current index of both arrays in the class
- accept_thread_check[] setup_server(){ //sets up the main part of the server
- //ipaddrs = new IPAddress[player_count];
- Socket[] listeners = new Socket[player_count]; //creates the listener array
- data = new data_array[player_count]; //creates the data_array array
- IPHostEntry local_host = Dns.GetHostEntry(Dns.GetHostName()); //gets the local IP
- IPAddress local_ip = local_host.AddressList[0]; //gets the local IP
- IPEndPoint localEndPoint = new IPEndPoint(local_ip, 0); //gets the local IP
- for(int iter = 0; iter < player_count; iter++){
- listeners[iter].Bind(localEndPoint); //sets up listeners on the local IP
- listeners[iter].Listen(player_count); //sets up listeners on the local IP
- }
- Thread[] accepter_threads = new Thread[player_count]; //creates the array to hold the accept threads
- accept_thread_check[] accept_thread_check_arr_local = new accept_thread_check[player_count]; //array of the class for the accept threads
- for(int iter_i = 0; iter_i < player_count; iter_i++){
- accept_thread_check_arr_local[iter_i] = new accept_thread_check(); //populates the accept thread check array
- }
- for(int iter = 0; iter < player_count; iter++){
- accepter_threads[iter] = new Thread(() => accept_socket_thread(listeners[iter], accept_thread_check_arr_local[iter]));
- accepter_threads[iter].Start(); //creates the threads within the accept threads array
- }
- return accept_thread_check_arr_local; //return the refernce to the array of the class
- }
- void accept_socket_thread(Socket listener, accept_thread_check is_done){ //thread to accept connections
- is_done.connection = listener.Accept(); //accept() is blocking, asynchronous Sockets will come later
- is_done.done = true;
- }
- Socket server_accept_conn(accept_thread_check[] accept_thread_check_arr){ //get the connected sockets
- for(int iter = 0; iter < player_count; iter++){
- if(accept_thread_check_arr[iter].done){
- return accept_thread_check_arr[iter].connection; //if there is a connection, return the socket
- }
- }
- return null; //otherwise, return nothing
- }
- void read_socket_conn(){ //thread to read data on connections
- while(true){ //own thread, run forever
- for(int iter = 0; iter < player_count; iter++){ //for each possible connection, there may be data. update to come to only check active connections
- if(data[iter].connection.Available > 0){ //receiving data
- data[iter].data_double_temp = new double[data[iter].data_double.Length]; //set the size of the temp
- data[iter].data_double_temp = data[iter].data_double; //preserve the original data
- data[iter].data_double = new double[data[iter].data_double_temp.Length+1]; //increase the size of the array by 1
- for(int resize = 0; resize < data[iter].data_double_temp.Length; resize++){
- data[iter].data_double[resize] = data[iter].data_double_temp[resize]; //copy the old into the new
- }
- data[iter].data_byte = new byte[data[iter].connection.Available]; //byte array to receive the data in
- data[iter].connection.Receive(data[iter].data_byte); //receive the data
- data[iter].data_double[data[iter].data_double.Length] = BitConverter.ToDouble(data[iter].data_byte, 0); //convert bytes to double, add to array
- }
- }
- for(int iter = 0; iter < player_count; iter++){ //sending data
- //todo:
- //find way to send data to all connections except connection received from
- //find way to send to self (if received from outsite source)
- if(data[iter].data_double.Length > 0){ //if there is data to be sent
- for(int send_iter = 0; send_iter < data[iter].data_double.Length; send_iter++){ //for each double in the array
- data[iter].connection.Send(BitConverter.GetBytes(data[iter].data_double[send_iter])); //convert it to bytes, send it
- data[iter].data_double_temp = new double[data[iter].data_double.Length]; //set the size of the temp array
- data[iter].data_double_temp = data[iter].data_double; //preserve the original data
- data[iter].data_double = new double[data[iter].data_double_temp.Length-1]; //decrease the size of the array by 1
- for(int resize = 1; resize < data[iter].data_double.Length; resize++){
- data[iter].data_double[resize] = data[iter].data_double_temp[resize]; //copy the old into the new, minus 1 entry (entry is already sent)
- }
- }
- }
- }
- }
- }
- accept_thread_check[] accept_thread_check_arr; //array of class objects
- // Use this for initialization
- void Start (){
- if(player_count < 1){ //if the amount of players was not set when this script is called
- player_count = 1; //make sure there is at least 1 player
- }
- accept_thread_check_arr = new accept_thread_check[player_count]; //set the array size
- accept_thread_check_arr = setup_server(); //populate the waiting-to-accept array
- holder_obj.s_holder = new Socket[player_count]; //initialize the socket_holder
- holder_obj.t_holder = new Thread[player_count]; //and the thread_holder
- }
- double conn_check_wait = 0.5; //time to wait between checking for new connections (to ease comp usage)
- double next_check = 0; //when the next check will happen
- Socket temp; //a temporary socket for checking connections, in case it returns null
- // Update is called once per frame (Unity method)
- void Update () {
- if(Time.time > next_check){ //if enough time has passed
- next_check = Time.time + conn_check_wait; //set the next_check time
- temp = server_accept_conn(accept_thread_check_arr); //accept the connection (store in temp in case it is null)
- if(temp != null){ //if there is a connection
- holder_obj.s_holder[holder_obj_index] = temp; //store it in the holder_obj array
- holder_obj_index++; //increase the index for the next entry
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement