1. 程式人生 > >Unity3d使用Socket與java伺服器通訊

Unity3d使用Socket與java伺服器通訊

---------------------------客戶端----------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;


/*
 * 
 *Socket客戶端通訊類
 * 
 * lm
 */
public class SocketHelper
{

    private static SocketHelper socketHelper=new SocketHelper();

    private Socket socket;


    //餓漢模式
    public static SocketHelper GetInstance()
    {
        return socketHelper;
    }

    private SocketHelper() {

        //採用TCP方式連線
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        //伺服器IP地址
        IPAddress address = IPAddress.Parse("127.0.0.1");

        //伺服器埠
        IPEndPoint endpoint = new IPEndPoint(address,8000);

        //非同步連線,連線成功呼叫connectCallback方法
        IAsyncResult result = socket.BeginConnect(endpoint, new AsyncCallback(ConnectCallback), socket);

        //這裡做一個超時的監測,當連線超過5秒還沒成功表示超時
        bool success = result.AsyncWaitHandle.WaitOne(5000, true);
        if (!success)
        {
            //超時
            Closed();
            Debug.Log("connect Time Out");
        }
        else
        {
            //與socket建立連線成功,開啟執行緒接受服務端資料。
            Thread thread = new Thread(new ThreadStart(ReceiveSorket));
            thread.IsBackground = true;
            thread.Start();
        }

    }

    private void ConnectCallback(IAsyncResult asyncConnect)
    {
        Debug.Log("connect success");
    }

    private void ReceiveSorket()
    {
        //在這個執行緒中接受伺服器返回的資料
        while (true)
        {

            if (!socket.Connected)
            {
                //與伺服器斷開連線跳出迴圈
                Debug.Log("Failed to clientSocket server.");
                socket.Close();
                break;
            }
            try
            {
                //接受資料儲存至bytes當中
                byte[] bytes = new byte[4096];
                //Receive方法中會一直等待服務端回發訊息
                //如果沒有回發會一直在這裡等著。
                int i = socket.Receive(bytes);
                if (i <= 0)
                {
                    socket.Close();
                    break;
                }
                Debug.Log(System.Text.Encoding.Default.GetString(bytes));
            }
            catch (Exception e)
            {
                Debug.Log("Failed to clientSocket error." + e);
                socket.Close();
                break;
            }
        }
    }



    //關閉Socket
    public void Closed()
    {
        if (socket != null && socket.Connected)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }
        socket = null;
    }



    //向服務端傳送一條字串
    //一般不會發送字串 應該是傳送資料包
    public void SendMessage(string str)
    {
        byte[] msg = Encoding.UTF8.GetBytes(str);

        if (!socket.Connected)
        {
            socket.Close();
            return;
        }
        try
        {
            IAsyncResult asyncSend = socket.BeginSend(msg, 0, msg.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
            bool success = asyncSend.AsyncWaitHandle.WaitOne(5000, true);
            if (!success)
            {
                socket.Close();
                Debug.Log("Failed to SendMessage server.");
            }
        }
        catch
        {
            Debug.Log("send message error");
        }
    }



    private void SendCallback(IAsyncResult asyncConnect)
    {
        Debug.Log("send success");
    }


}

----------------------------------伺服器-------------------------------------------------
package org.u3d.server;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


/**
 * 
 * unity3d 服務端
 * 
 * 
 * 
 * @author lm
 *
 */
public class U3dServer implements Runnable {

	public void run() {
		
		ServerSocket u3dServerSocket = null;

		while(true){
			
			try {
				
				u3dServerSocket=new ServerSocket(8000);
				
				System.out.println("u3d服務已經啟動,監聽8000埠");
				
				while (true) {
					Socket socket = u3dServerSocket.accept();
					System.out.println("客戶端接入");
					new RequestReceiver(socket).start();
				}
				
				
			} catch (IOException e) {
				System.err.println("伺服器接入失敗");
				if (u3dServerSocket != null) {
					try {
						u3dServerSocket.close();
					} catch (IOException ioe) {
					}
					u3dServerSocket = null;
				}
			}
			
			// 服務延時重啟
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {

			}
			
		}
		
		
	}
	
	
	
	/**
	 * 客戶端請求接收執行緒
	 * @author lm
	 *
	 */
	class RequestReceiver extends Thread {

		/** 報文長度位元組數 */
		private int messageLengthBytes = 1024;

		private Socket socket;

		/** socket輸入處理流 */
		private BufferedInputStream bis = null;
		

		public RequestReceiver(Socket socket) {
			this.socket = socket;
		}

		@Override
		public void run() {
			try {
				bis = new BufferedInputStream(socket.getInputStream());
				byte[] buf = new byte[messageLengthBytes];
				
				/**
				 * 在Socket報文傳輸過程中,應該明確報文的域
				 */
				while (true) {
			
					/*
					 * 這種業務處理方式是根據不同的報文域,開啟執行緒,採用不同的業務邏輯進行處理
					 * 依據業務需求而定 
					 */
					//new RequestHandler(socket, buf).start(); 
					bis.read(buf);
					System.out.println(new String(buf,"utf-8"));
					Message msg=new GeneralMessage("i am server");
					msg.write(socket.getOutputStream());
				}
				
			} catch (IOException e) {
				System.err.println("讀取報文出錯");
			} finally {
				if (socket != null) {
					try {
						socket.close();
					} catch (IOException e) {
					}
					socket = null;
				}
			}
			
		}
	}
	
	
	/**
	 * 描述: 請求處理器
	 * 
	 */
/*	class RequestHandler extends Thread {


		

	}
*/

}
<pre name="code" class="java">public class U3dApplication {
	
	private static U3dApplication instance = null;

	private boolean stop;

	private U3dApplication() {
	}

	public static synchronized U3dApplication getApplication() {
		if (instance == null) {
			instance = new U3dApplication();
		}
		return instance;
	}
	
	public void start() {
		init();
		new Thread(new U3dServer(), "U3d Server").start();

		while (!stop) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				getApplication().stopMe();
			}
		});
		getApplication().start();
	}
	
	public void stopMe() {
		System.out.println("系統即將關閉...");
	}
	
	
	/**
	 * 初始化系統
	 */
	private void init() {
		
	}

}