Server

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Code)
(Updated to fix a blocking issue.)
Line 105: Line 105:
 
static public int PutMessage(string sendMsg){
 
static public int PutMessage(string sendMsg){
 
if(theServer!=null){
 
if(theServer!=null){
if(theServer.m_sBuffer.Count>1000) theServer.m_sBuffer.Clear(); //if there is a backlog of more than 1000 messages clear the queue
+
if(theServer.m_sBuffer.Count>100) theServer.m_sBuffer.Clear(); //if there is a backlog of more than 1000 messages clear the queue
 
return theServer.m_sBuffer.Add(sendMsg);
 
return theServer.m_sBuffer.Add(sendMsg);
 
}
 
}
Line 182: Line 182:
 
         for( int i = 0; i < listenList.Count; i++ ){
 
         for( int i = 0; i < listenList.Count; i++ ){
 
             Socket newSocket = ((Socket)listenList[i]).Accept();
 
             Socket newSocket = ((Socket)listenList[i]).Accept();
 +
newSocket.Blocking=false;
 
             m_Connections.Add(newSocket);
 
             m_Connections.Add(newSocket);
 
             m_ByteBuffer.Add(new ArrayList());
 
             m_ByteBuffer.Add(new ArrayList());
Line 218: Line 219:
 
}
 
}
 
catch (SocketException e) {
 
catch (SocketException e) {
 +
Debug.Log(e.StackTrace);
 +
Debug.Log(e.NativeErrorCode + " " + e.Message);
 
if(e.NativeErrorCode.Equals(10054) || e.NativeErrorCode.Equals(10058)){
 
if(e.NativeErrorCode.Equals(10054) || e.NativeErrorCode.Equals(10058)){
 
socket.Close();
 
socket.Close();

Revision as of 01:24, 9 March 2007

Server Script

The Server script opens a .NET socket on port 9349 (editable in the editor) and listens for incoming TCP connections. This was based on the server portion of the NetworkCursor script. This sends and receives arbitrary data through the connected sockets.

C# Code

<csharp> using UnityEngine; using System.Collections; using System.Net.Sockets; using System.Net; using System.Text;

public class Server : MonoBehaviour { public int port = 9349;

   static Server theServer;
   
   private Socket m_Socket;
   
   ArrayList m_Connections = new ArrayList ();
   
   ArrayList m_rBuffer = new ArrayList ();

ArrayList m_sBuffer = new ArrayList ();

   ArrayList m_ByteBuffer = new ArrayList ();


   void Awake ()
   {

Init();

   }
   void Init(){

if(m_Socket==null){ m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint ipLocal = new IPEndPoint ( IPAddress.Any , port);

m_Socket.Bind( ipLocal );

//start listening...

m_Socket.Listen (100);

theServer = this;

// Debug.Log("Listening on: " + ((IPEndPoint)m_Socket.LocalEndPoint).Address + ":" + ((IPEndPoint)m_Socket.LocalEndPoint).Port); } }

   void OnApplicationQuit ()
   {
       Cleanup();
   }

void OnEnable(){ Init(); }

void OnDisable(){ //Clear out the listening socket so that we can listen again on enable if (m_Socket != null){ m_Socket.Shutdown(SocketShutdown.Both);

           m_Socket.Close();

m_Socket = null; } }

   void Cleanup ()
   {
       if (m_Socket != null){

m_Socket.Shutdown(SocketShutdown.Both);

           m_Socket.Close();

m_Socket = null; }

       foreach (Socket con in m_Connections)
           con.Close();
       m_Connections.Clear();
   }   
   ~Server ()
   {
       Cleanup();      
   }
   


//Get a message from the received queue

   static public string GetMessage (){
       if(theServer!=null){	

if (theServer.m_rBuffer.Count == 0)

       	{
       	    return null;
       	}
       	else
       	{
       	    string readMsg = (string)theServer.m_rBuffer[0];
       	    theServer.m_rBuffer.RemoveAt(0);
       	    return readMsg;
       	}

} else return null;

   }

//Put a message in the outgoing queue static public int PutMessage(string sendMsg){ if(theServer!=null){ if(theServer.m_sBuffer.Count>100) theServer.m_sBuffer.Clear(); //if there is a backlog of more than 1000 messages clear the queue return theServer.m_sBuffer.Add(sendMsg); } else return -1; }

//Convert a string to a byte array static ArrayList StringToBytes(string theString){ ArrayList bytes=new ArrayList(); foreach(char c in theString.ToCharArray()){ bytes.Add((byte)c); } return bytes; }

//Returns true if there are messages waiting to be read in the received queue static public int MessageAvailable(){ if(theServer!=null) return theServer.m_rBuffer.Count; else return -1; }

//Returns true if there are connections in the connection list static public bool Connected(){ if(theServer!=null && theServer.m_Connections.Count>0) return true; else return false; }

//Number of messages waiting to be sent static public int SendBufferBackLog(){ if(theServer!=null)return theServer.m_sBuffer.Count; else return -1; }

//Clear the send buffer static public void ClearSendBuffer(){ if(theServer!=null)theServer.m_sBuffer.Clear(); return; }

//Check if a socket is still connected, questionable if this is working in Unity/Mono static bool isConnected(Socket socket){ bool blockingState = socket.Blocking; bool connected = false; try { byte [] tmp = new byte[1];

socket.Blocking = false; socket.Send(tmp, 0, 0); connected = true; } catch (SocketException e) { // 10035 == WSAEWOULDBLOCK if (e.NativeErrorCode.Equals(10035)) connected = true; else { connected = false; } } finally { socket.Blocking = blockingState; } return connected; }


   void LateUpdate ()  {
       // Accept any incoming connections!
       ArrayList listenList = new ArrayList();
       listenList.Add(m_Socket);
       Socket.Select(listenList, null, null, 1000);
       for( int i = 0; i < listenList.Count; i++ ){
           Socket newSocket = ((Socket)listenList[i]).Accept();

newSocket.Blocking=false;

           m_Connections.Add(newSocket);
           m_ByteBuffer.Add(new ArrayList());
           Debug.Log("Did connect");
       }
       if (m_Connections.Count != 0){

ArrayList connections = new ArrayList (m_Connections); //Remove closed sockets from the list foreach (Socket socket in connections){ if(isConnected(socket)==false){ socket.Close(); theServer.m_ByteBuffer.RemoveAt(m_Connections.IndexOf(socket)); theServer.m_Connections.Remove(socket); } } }


       // Read & Write data from the connections!
       if (m_Connections.Count != 0){

// Write data to connections ArrayList connections = new ArrayList (m_Connections);

           Socket.Select(null, connections, null, 1000);

while (theServer.m_sBuffer.Count>0){ byte[] sndBytes = new byte[((string)theServer.m_sBuffer[0]).Length]; string theString = (string)theServer.m_sBuffer[0]; for(int i=0;i<sndBytes.Length;i++){ sndBytes[i]=(byte)theString[i]; } foreach(Socket socket in connections){ try{ if(socket.Connected==false)break; socket.Send(sndBytes); } catch (SocketException e) { Debug.Log(e.StackTrace); Debug.Log(e.NativeErrorCode + " " + e.Message); if(e.NativeErrorCode.Equals(10054) || e.NativeErrorCode.Equals(10058)){ socket.Close(); theServer.m_ByteBuffer.RemoveAt(m_Connections.IndexOf(socket)); theServer.m_Connections.Remove(socket); }

} } theServer.m_sBuffer.RemoveAt(0); }

connections = new ArrayList (m_Connections);

           Socket.Select(connections, null, null, 1000);
           // Go through all sockets that have data incoming!
           foreach (Socket socket in connections)
           {	

ArrayList buffer = null; try{ if(socket.Connected==true){ byte[] receivedbytes = new byte[512];

buffer = (ArrayList)m_ByteBuffer[m_Connections.IndexOf(socket)]; int read = socket.Receive(receivedbytes);

if(receivedbytes[0]!=0) { for (int i=0;i<read;i++) buffer.Add(receivedbytes[i]); } } } catch (SocketException e) { if(e.NativeErrorCode.Equals(10054) || e.NativeErrorCode.Equals(10058)){ socket.Close(); theServer.m_ByteBuffer.RemoveAt(m_Connections.IndexOf(socket)); theServer.m_Connections.Remove(socket); }

}


while (buffer.Count > 0){

                       ArrayList thismsgBytes = new ArrayList(buffer);

int length=thismsgBytes.Count;

                       if (thismsgBytes.Count != length) Debug.Log("Bug");
                       buffer.RemoveRange(0, length);
                       byte[] readbytes = (byte[])thismsgBytes.ToArray(typeof(byte));

string readString = ""; foreach(byte b in readbytes){ readString+=(char)b; }

// Debug.Log(readString);

                       theServer.m_rBuffer.Add(readString);
                       if (theServer != this) Debug.Log("Bug");   
               }


} } }

} </csharp>

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox