Unity 3 D入門2:Socket初探査


ここ数日Socketインタラクションを検討した.    ネット上の資料でSocketに関する最初のDemoを作りましたが、あまり成熟していませんが、個人的には比較的完全な感じがします.各タイプのデータの転送受付はありますが、中にはfloatタイプもやっています(Unityをやるべきだと感じているので).    機能面では,マルチユーザインタラクションをテストするために,Demo上で4個のSocket 4個のスレッドを開いてデータを受け取った.サービス側がユーザに離脱を通知する機能を実現した.    本体には、ワードライブラリを追加する必要があります.中国語を表示できません.        プロジェクトディレクトリ:
 
    次のコードは次のとおりです.
クライアントコード:
 using UnityEngine;
 using System;
 using System.Collections;
 using LSocket.Net;
 using LSocket.Type;
 using LSocket.cmd;

    public class SocketDemo : MonoBehaviour
    {
        public UnitySocket[] socket;
        public String[] textAreaString;
        public String[] textFieldString;
        public GUISkin mySkin;
        // Use this for initialization
        void Start()
        {
            socket = new UnitySocket[4];
            textAreaString = new String[12];
            for (int i = 0; i < 12; i++)
            {
                textAreaString[i] = "";
            }
            textFieldString = new String[4];
            for(int i=0;i<4;i++){
                textFieldString[i] = "";
            }
        }

        // Update is called once per frame
        void Update()
        {

        }

        void OnGUI()
        {
            GUI.skin = mySkin;
            for (int i = 0; i < 4; i++)
            {
                String s = textAreaString[i * 3] + "
" + textAreaString[i * 3 + 1] + "
" + textAreaString[i * 3 + 2]; GUI.TextArea(new Rect(i % 2 * Screen.width / 2, i / 2 * (Screen.height / 2) + 50, 100, 60), s); textFieldString[i] = GUI.TextField(new Rect(i % 2 * Screen.width / 2+50, i / 2 * (Screen.height / 2), 100, 20), textFieldString[i]); if (GUI.Button(new Rect(i % 2 * Screen.width / 2, i / 2 * (Screen.height / 2), 40, 20), " ")) { socket[i] = null; socket[i] = new UnitySocket(); socket[i].SocketConnection("192.168.0.8", 10000, this, i); socket[i].DoLogin(textFieldString[i]); } else if (GUI.Button(new Rect(i % 2 * Screen.width / 2, i / 2 *( Screen.height / 2) + 25, 40, 20), " ")) { if (socket[i] != null) { socket[i].close(); socket[i] = null; } } } if (GUI.Button(new Rect(Screen.width - 60, Screen.height - 30, 60, 30), " ")) { Application.Quit(); } } }

 
namespace LSocket.Net 
{ /**
 * 
 * @author feng ,qq:313785443
 * @date 2010-12-23
 *
 */

    //      :  c# socket       
  	using UnityEngine; 
	using System; 
	using System.Net.Sockets; 
	using System.Net; 
	using System.Collections; 
	using System.Text;
    using System.Threading;
	using LSocket.Type; 
	using LSocket.cmd;


    class SocketThread
    {

        UnitySocket socket;
        SocketDemo demo;
        int idx;

        public SocketThread(UnitySocket socket, SocketDemo demo, int idx)
        {
            this.socket = socket;
            this.demo = demo;
            this.idx = idx;
        }

        public void run()
        {
            while (true)
            {
                try
                {
                    String s = socket.ReceiveString();
                    demo.textAreaString[idx * 3] = demo.textAreaString[idx * 3 + 1];
                    demo.textAreaString[idx * 3 + 1] = demo.textAreaString[idx * 3 + 2];
                    demo.textAreaString[idx * 3 + 2] = s;
                    MonoBehaviour.print(s + " " + idx);
                }
                catch (Exception e)
                {
                    MonoBehaviour.print(e.ToString());
                    socket.t.Abort();
                }
            }
        }

    }

    public class UnitySocket 
    { 
        public Socket mSocket = null;
        public Thread t=null;
        private SocketThread st=null;
        public SocketDemo demo=null;

        public UnitySocket() 
        { 
             
        } 
		public void SocketConnection(string LocalIP, int LocalPort,SocketDemo demo,int idx) 
		{
            this.demo=demo;
			mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
            try 
            { 
				 
                IPAddress ip = IPAddress.Parse(LocalIP); 
                IPEndPoint ipe = new IPEndPoint(ip, LocalPort); 
				mSocket.Connect(ipe);
                st =new SocketThread(this, demo, idx);
                t = new Thread(new ThreadStart(st.run));
                t.Start();
            } 
            catch (Exception e) 
            {
                MonoBehaviour.print(e.ToString());
            } 
		}
        
        public void close(){
            mSocket.Close(0);
            mSocket=null;
        }

        public void DoLogin(String userName){
            try
            {
                Send(CommandID.LOGIN);
                Send(userName);
            }catch(Exception e){
                MonoBehaviour.print(e.ToString());
            }
        }


        public void Send(float data){
            byte[] longth = TypeConvert.getBytes(data, true);
            mSocket.Send(longth);
        }

        public float ReceiveFloat()
        {
            byte[] recvBytes = new byte[4];
            mSocket.Receive(recvBytes, 4, 0);//            
            float data = TypeConvert.getFloat(recvBytes, true);
            return data;
        } 

		public void Send(short data) 
		{ 
			byte[] longth=TypeConvert.getBytes(data,true); 
			mSocket.Send(longth);
		} 
		 
		public void Send(long data) 
		{ 
			byte[] longth=TypeConvert.getBytes(data,true); 
			mSocket.Send(longth); 
		} 
		 
		public void Send(int data) 
		{ 
			byte[] longth=TypeConvert.getBytes(data,true); 
			mSocket.Send(longth); 
			 
		} 
		 
		public void Send(string data) 
		{ 
			byte[] longth=Encoding.UTF8.GetBytes(data);
            Send(longth.Length);
			mSocket.Send(longth); 
			 
		} 
		 
		public short ReceiveShort() 
		{ 
			 byte[] recvBytes = new byte[2]; 
             mSocket.Receive(recvBytes,2,0);//            
			 short data=TypeConvert.getShort(recvBytes,true); 
			 return data; 
		} 
		 
		public int ReceiveInt() 
		{ 
			 byte[] recvBytes = new byte[4]; 
             mSocket.Receive(recvBytes,4,0);//            
			 int data=TypeConvert.getInt(recvBytes,true); 
			 return data; 
		} 
		 
		public long ReceiveLong() 
		{ 
			 byte[] recvBytes = new byte[8]; 
             mSocket.Receive(recvBytes,8,0);//            
			 long data=TypeConvert.getLong(recvBytes,true); 
			 return data; 
		} 
		 
		public String ReceiveString() 
		{ 
             int length = ReceiveInt();
             MonoBehaviour.print("Stringlen="+length);
			 byte[] recvBytes = new byte[length]; 
             mSocket.Receive(recvBytes,length,0);//            
             String data = Encoding.UTF8.GetString(recvBytes); 
			 return data; 
		} 
		 
		 
	}
} 

 
namespace LSocket.Type
{
    using UnityEngine;
    using System.Collections;

    public class TypeConvert
    {

        public TypeConvert()
        {
        }

        public  static byte[] getBytes(float s,bool asc){
            int buf = (int)(s * 100);
            return getBytes(buf,asc);
        }
    
         public static float getFloat(byte[] buf,bool asc){
            int i=getInt(buf,asc);
            float s=(float)i;
            return s/100;
        }

        public static byte[] getBytes(short s, bool asc)
        {
            byte[] buf = new byte[2];
            if (asc)
            {
                for (int i = buf.Length - 1; i >= 0; i--)
                {
                    buf[i] = (byte)(s & 0x00ff);
                    s >>= 8;
                }
            }
            else
            {
                for (int i = 0; i < buf.Length; i++)
                {

                    buf[i] = (byte)(s & 0x00ff);
                    s >>= 8;
                }
            }
            return buf;
        }
        public static byte[] getBytes(int s, bool asc)
        {
            byte[] buf = new byte[4];
            if (asc)
                for (int i = buf.Length - 1; i >= 0; i--)
                {
                    buf[i] = (byte)(s & 0x000000ff);
                    s >>= 8;
                }
            else
                for (int i = 0; i < buf.Length; i++)
                {
                    buf[i] = (byte)(s & 0x000000ff);
                    s >>= 8;
                }
            return buf;
        }

        public static byte[] getBytes(long s, bool asc)
        {
            byte[] buf = new byte[8];
            if (asc)
                for (int i = buf.Length - 1; i >= 0; i--)
                {
                    buf[i] = (byte)(s & 0x00000000000000ff);
                    s >>= 8;
                }
            else
                for (int i = 0; i < buf.Length; i++)
                {
                    buf[i] = (byte)(s & 0x00000000000000ff);
                    s >>= 8;
                }
            return buf;
        }
        public static short getShort(byte[] buf, bool asc)
        {
            if (buf == null)
            {
                //throw new IllegalArgumentException("byte array is null!");
            }
            if (buf.Length > 2)
            {
                //throw new IllegalArgumentException("byte array size > 2 !");
            }
            short r = 0;
            if (!asc)
                for (int i = buf.Length - 1; i >= 0; i--)
                {
                    r <<= 8;
                    r |= (short)(buf[i] & 0x00ff);
                }
            else
                for (int i = 0; i < buf.Length; i++)
                {
                    r <<= 8;
                    r |= (short)(buf[i] & 0x00ff);
                }
            return r;
        }
        public static int getInt(byte[] buf, bool asc)
        {
            if (buf == null)
            {
                // throw new IllegalArgumentException("byte array is null!");
            }
            if (buf.Length > 4)
            {
                //throw new IllegalArgumentException("byte array size > 4 !");
            }
            int r = 0;
            if (!asc)
                for (int i = buf.Length - 1; i >= 0; i--)
                {
                    r <<= 8;
                    r |= (buf[i] & 0x000000ff);
                }
            else
                for (int i = 0; i < buf.Length; i++)
                {
                    r <<= 8;
                    r |= (buf[i] & 0x000000ff);
                }
            return r;
        }
        public static long getLong(byte[] buf, bool asc)
        {
            if (buf == null)
            {
                //throw new IllegalArgumentException("byte array is null!");
            }
            if (buf.Length > 8)
            {
                //throw new IllegalArgumentException("byte array size > 8 !");
            }
            long r = 0;
            if (!asc)
                for (int i = buf.Length - 1; i >= 0; i--)
                {
                    r <<= 8;
                    r |= (buf[i] & 0x00000000000000ff);
                }
            else
                for (int i = 0; i < buf.Length; i++)
                {
                    r <<= 8;
                    r |= (buf[i] & 0x00000000000000ff);
                }
            return r;
        }
    }
}

 
namespace LSocket.cmd
{
    public class CommandID
    {
        /**        **/
        public static int LOGIN = 1001;
     
    }
}

サーバ側コードJava:
package com.unity.socket;


import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;


public class SocketServer {
    private HashMap userMap;

    public  SocketServer(){
         userMap=new HashMap();
    }

    public static void main(String[] args){
        new SocketServer().startServer();
    }

    public void startServer()
	{
		try
		{
			ServerSocket serverSocket = new ServerSocket(10000);
			System.out.println("     ");
            while (true){
                Socket socket = serverSocket.accept();
                System.out.println("        ");
                new UserThread(socket,userMap).start();
            }

        }catch (Exception e){
             System.out.println("       !" + e);
        }
    }
}

 
package com.unity.socket;

import java.net.Socket;

public class User {
    private String name;
    private Socket socket;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

}

 
package com.unity.socket;

import java.io.*;
import java.net.Socket;
import java.util.Iterator;

import java.io.ByteArrayOutputStream;

import java.io.DataOutputStream;
import java.util.HashMap;


public class UserThread extends Thread{
    /**        **/
	public static final int 			ERROR = 0;
	/**        **/
	public static final int 			LOGIN = 1001;
    private Socket socket;
    private HashMap userMap;
    private User user;
    private ByteArrayOutputStream byteOutput;
    private DataOutputStream output;
    private DataInputStream input;

    public UserThread(Socket socket,HashMap userMap){
        this.socket=socket;
        this.userMap=userMap;
    }

    //     2   output
	private void initOutput()
	{
		byteOutput = new ByteArrayOutputStream();
		output = new DataOutputStream(byteOutput);
	}

    public void sendAllUser(byte[] bytes) throws Exception
	{
		for(Iterator it = userMap.values().iterator(); it.hasNext();)
		{
			sendMessage(it.next().getSocket(),bytes);
		}
	}

    public void sendMessage(Socket socket,byte[] bytes) throws Exception
	{
		DataOutputStream dataOutput = new DataOutputStream(socket.getOutputStream());
		dataOutput.write(bytes);
		dataOutput.flush();
	}

    public short readShort()throws IOException{
          byte[] buf=new byte[2];
          input.read(buf);
          return ConvertType.getShort(buf,true);
    }

    public int readInt()throws IOException{
          byte[] buf=new byte[4];
          input.read(buf);
          return ConvertType.getInt(buf, true);
    }

    public long readLong()throws IOException{
          byte[] buf=new byte[8];
          input.read(buf);
          return ConvertType.getLong(buf, true);
    }

   public float readFloat()throws IOException{
          byte[] buf=new byte[4];
          input.read(buf);
          return ConvertType.getFloat(buf, true);
    }

    public String readString()throws IOException{
          int length=readInt();
          byte[] buf=new byte[length];
          input.read(buf);
          return new String(buf);
    }



    public void run(){
        try{
            input = new DataInputStream(socket.getInputStream()) ;
            while (true){
                int cmd=0;
                cmd=readInt();
                System.out.println("   :"+cmd);
                if(cmd==ERROR){   //   
                    userMap.remove(user.getName());
                    Message msg=new Message();
                    msg.writeString(user.getName()+"   ");
                    System.out.println(user.getName()+"   ");
                    try{
                         sendAllUser(msg.getBuff().array());
                    }catch (Exception ex){
                         System.out.println("sendAllUserErr: "+ex.toString());
                     }
                    break;
                }
                switch (cmd){
                    case LOGIN:
                        System.out.println("     ");
                        String userName = readString();
                        user = new User();
                        user.setName(userName);
                        user.setSocket(socket);
                        System.out.println(userName);
                        if(userMap.containsKey(userName)) {
                            Message msg=new Message();
                            msg.writeString("    ");
							sendMessage(socket,msg.getBuff().array());
                            msg.clear();
                            msg=null;
                        }else{
                            System.out.println("      :" + userName);
							userMap.put(userName, user);
							initOutput();
                            Message msg=new Message();
                            msg.writeString("    ");
							sendMessage(socket,msg.getBuff().array());
                            msg.clear();
                            msg=null;
                        }
                        break;
                }
            }
        }catch (Exception e){
             e.printStackTrace();
             userMap.remove(user.getName());
             Message msg=new Message();
             msg.writeString(user.getName()+"   ");
            System.out.println(user.getName()+"   ");
            try{
                sendAllUser(msg.getBuff().array());
            }catch (Exception ex){
                System.out.println("sendAllUserErr: "+ex.toString());
            }

        }
    }
}

 
package com.unity.socket;

import java.nio.ByteBuffer;

import com.unity.socket.ConvertType;

public class Message {
    private ByteBuffer buf;
    public Message(){
        buf=ByteBuffer.allocate(0);
    }

    public ByteBuffer getBuff(){
        return  buf;
    }

    public void clear(){
        buf.clear();
    }

    public void addSize(int len){
        ByteBuffer tmpbuf=ByteBuffer.allocate(buf.capacity()+len);
        buf=null;
        buf=tmpbuf;
    }

    public void writeByte(byte b){
       addSize(1);
       buf.put(b);
    }

    public void write(byte[] b){
        addSize(b.length);
        buf.put(b);
    }

     public void writeShort(short b){
        addSize(2);
        buf.put(ConvertType.getBytes(b,true));
    }

    public void writeInt(int b){
        addSize(4);
        buf.put(ConvertType.getBytes(b,true));
    }

     public void writeLong(long b){
        addSize(8);
        buf.put(ConvertType.getBytes(b,true));
    }

    public void writeFloat(float b){
        addSize(4);
        buf.put(ConvertType.getBytes(b,true)) ;
    }

    public void writeString(String s){
        byte[] b= new byte[200];
        b=s.getBytes();
        addSize(4+b.length);
        buf.put(ConvertType.getBytes(b.length,true));
        buf.put(s.getBytes());
    }
}

 
package com.unity.socket;

public class ConvertType 
{
	public ConvertType()
	{
		
	}

    public final static byte[] getBytes(float s,boolean asc){
        int buf=(int)(s*100);
        return getBytes(buf,asc);
    }

     public final static float getFloat(byte[] buf,boolean asc){
        int i=getInt(buf,asc);
        float s=(float)i;
        return s/100;
    }

	public final static byte[] getBytes(short s, boolean asc)
	{
	    byte[] buf = new byte[2];
	    if (asc) 
	    {
		    for (int i = buf.length - 1; i >= 0; i--) 
		    {        
		    	buf[i] = (byte) (s & 0x00ff);
		        s >>= 8;
		     }
	    }
	    else
	    {  
	    	for (int i = 0; i < buf.length; i++) 
	    	{
	   
		        buf[i] = (byte) (s & 0x00ff);
		        s >>= 8;
	    	}
	    }
	    return buf;
	  }
	  public final static byte[] getBytes(int s, boolean asc) {
	    byte[] buf = new byte[4];
	    if (asc)
	      for (int i = buf.length - 1; i >= 0; i--) {
	        buf[i] = (byte) (s & 0x000000ff);
	        s >>= 8;
	      }
	    else
	      for (int i = 0; i < buf.length; i++) {
	        buf[i] = (byte) (s & 0x000000ff);
	        s >>= 8;
	      }
	    return buf;
	  }
	  public final static byte[] getBytes(long s, boolean asc) {
	    byte[] buf = new byte[8];
	    if (asc)
	      for (int i = buf.length - 1; i >= 0; i--) {
	        buf[i] = (byte) (s & 0x00000000000000ff);
	        s >>= 8;
	      }
	    else
	      for (int i = 0; i < buf.length; i++) {
	        buf[i] = (byte) (s & 0x00000000000000ff);
	        s >>= 8;
	      }
	    return buf;
	  }
	  public final static short getShort(byte[] buf, boolean asc) 
	  {
		    if (buf == null) 
		    {
		      throw new IllegalArgumentException("byte array is null!");
		    }
		    if (buf.length > 2) 
		    {
		      throw new IllegalArgumentException("byte array size > 2 !");
		    }
		    short r = 0;
		    if (!asc)
		      for (int i = buf.length - 1; i >= 0; i--) {
		        r <<= 8;
		        r |= (buf[i] & 0x00ff);
		      }
		    else
		      for (int i = 0; i < buf.length; i++) {
		        r <<= 8;
		        r |= (buf[i] & 0x00ff);
		      }
		    return r;
	  }
	  public final static int getInt(byte[] buf, boolean asc) {
	    if (buf == null) {
	      throw new IllegalArgumentException("byte array is null!");
	    }
	    if (buf.length > 4) {
	      throw new IllegalArgumentException("byte array size > 4 !");
	    }
	    int r = 0;
	    if (!asc)
	      for (int i = buf.length - 1; i >= 0; i--) {
	        r <<= 8;
	        r |= (buf[i] & 0x000000ff);
	      }
	    else
	      for (int i = 0; i < buf.length; i++) {
	        r <<= 8;
	        r |= (buf[i] & 0x000000ff);
	      }
	    return r;
	  }
	  public final static long getLong(byte[] buf, boolean asc) {
	    if (buf == null) {
	      throw new IllegalArgumentException("byte array is null!");
	    }
	    if (buf.length > 8) {
	      throw new IllegalArgumentException("byte array size > 8 !");
	    }
	    long r = 0;
	    if (!asc)
	      for (int i = buf.length - 1; i >= 0; i--) {
	        r <<= 8;
	        r |= (buf[i] & 0x00000000000000ff);
	      }
	    else
	      for (int i = 0; i < buf.length; i++) {
	        r <<= 8;
	        r |= (buf[i] & 0x00000000000000ff);
	      }
	    return r;
      }
	
}

 
 
とても简単なdemo、一定の拡張性があって、工事のダウンロードを必要として见て、リンクをダウンロードします
http://download.csdn.net/detail/genius840215/4187126