加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Unity3D网络连接-Socket(转载)

(2012-07-31 16:29:31)
标签:

杂谈

原文: http://blog.csdn.net/genius840215/article/details/7411749

这几天研究了下Socket交互。
    通过网上的资料做了有关Socket的第一个Demo,虽然不是很成熟,但个人感觉已经相对比较完整了。各类型数据的传输接受都有,其中也做了float类型的(因为我感觉做Unity应该用的着)。
    功能方面,为了测试多用户交互,我在Demo上开启了4个Socket 4个线程接受数据。实现了服务端通知用户进入 离开功能。
    真机上,需要加上字库,要不无法显示中文。
    
    工程目录:

 http://my.csdn.net/uploads/201203/30/1333093902_9843.png

    下面上代码:

客户端代码Unity3d:

1.SocketDemo .cs

 

 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] + "\n" + textAreaString[i * 3 + 1] + "\n" + 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();

            }


        }

    }

2.UnitySocket.cs

namespace LSocket.Net 

{


    // 描   述:封装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; 

 

 

}

3.TypeConvert.cs
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;
        }
    }
}

4.CommandID.cs
namespace LSocket.cmd
{
    public class CommandID
    {
       
        public static int LOGIN = 1001;
     
    }
}

服务器端代码 Java:
(1).
package com.unity.socket;


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


public class SocketServer {
    private HashMap<String,User> userMap;

    public  SocketServer(){
         userMap=new HashMap<String, User>();
    }

    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);
        }
    }
}

(2).
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;
    }

}

(3).
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<String,User> userMap;
    private User user;
    private ByteArrayOutputStream byteOutput;
    private DataOutputStream output;
    private DataInputStream input;

    public UserThread(Socket socket,HashMap<String,User> 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<User> 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());
            }

        }
    }
}

(4).
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());
    }
}

(5).
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;
      }
}


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有