2016-06-11 2 views
0

내가 유니티와 소켓 네트워킹 프로그램이 그래서 테스트 프로젝트를 만들어 테스트를위한 해당 프로젝트에 NetworkManager 클래스와 PacketManager 클래스를 추가 만들고 싶어 작동하지 않습니다.연합, 프로그램은

프로그램이 시작될 때 에 connect() 메서드를 호출하면 네트워크 연결이 성공합니다. 그리고 서버로 보내기 위해 패킷을 바이트 스트림으로 보내야합니다. 그래서 마샬링과 getBytes() 메서드 호출을 사용하여 PacketManager 클래스 (정적)를 만들었습니다. 그러나 그것은 작동하지 않습니다 (단합 프로그램이 종료되었습니다). 여기

내 스크립트입니다

Move.cs

using UnityEngine; 
using System.Collections; 
using System.Net.Sockets; 
using System.Net; 
using System; 
using System.Runtime.InteropServices; 

public class move : MonoBehaviour { 

    private NetworkManager nManager; 

    // Use this for initialization 
    void Start() { 
     Debug.Log ("start"); 

     nManager = new NetworkManager(); 
     nManager.connect(); 

     packet p = new packet(); 
     p.type = 100; 
     p.msg = "abcdabcd"; 

     byte[] array = PacketManager.getBytes (p); 

    } 

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

    } 
} 

NetworkManager.cs

using UnityEngine; 
using System.Collections; 
using System.Net.Sockets; 
using System.Net; 
using System; 
using System.Runtime.InteropServices; 

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public struct packet 
{ 
    public int type; 
    public int number; 
    public int room; 
    public float x, y, z; 
    public float rotate; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)] 
    public string msg; 
} 

public class NetworkManager : MonoBehaviour 
{ 
    private const string serverIP = "127.0.0.1"; 
    private const int portNum = 9090; 
    private const int buffersize = 128; 

    private static TcpClient client = null; 
    private static NetworkStream netStream = null; 

    public NetworkManager() {} 

    public Boolean connect() 
    { 
     Boolean success = false; 

     try 
     { 
      Debug.Log("try to connenct.."); 
      client = new TcpClient(serverIP, portNum); 
      netStream = client.GetStream(); 
      Debug.Log("connected success!"); 

     } 
     catch (Exception e) 
     { 
      success = false; 
      Debug.Log(e.Message); 
     } 

     return success; 
    } 

    public void sendPacket(packet p) 
    { 
     byte[] array = PacketManager.getBytes(p); 
     netStream.Write(array, 0, buffersize); 
    } 

    public packet recvPacket() 
    { 
     packet p = new packet(); 
     byte[] bytebuffer = new Byte[buffersize]; 
     int totalByteRcvd = 0; 
     int bytesRcvd = 0; 

     while (totalByteRcvd < buffersize) 
     { 
      if ((bytesRcvd = netStream.Read(bytebuffer, totalByteRcvd, buffersize - totalByteRcvd)) == 0) 
      { 

       p = PacketManager.BytesToSturct<packet>(bytebuffer); 

       break; 
      } 
      totalByteRcvd += bytesRcvd; 
      Debug.Log("byte : " + totalByteRcvd); 
     } 

     return p; 
    } 

} 

PacketManager.cs

에서

byte[] array = PacketManager.getBytes (p); 

는, 로그 잘 인쇄되어 있습니다,하지만 난 어떤 방법 (이 방법뿐만 아니라)를 호출하는 경우, 프로그램 종료 :

using UnityEngine; 
using System.Collections; 
using System.Net.Sockets; 
using System.Net; 
using System; 
using System.Runtime.InteropServices; 

public class PacketManager : MonoBehaviour 
{ 

    public static byte[] getBytes(object str) 
    { 

     int size = Marshal.SizeOf(str); 
     byte[] arr = new byte[size]; 
     IntPtr ptr = Marshal.AllocHGlobal(size); 

     Marshal.StructureToPtr(str, ptr, true); 
     Marshal.Copy(ptr, arr, 0, size); 
     Marshal.FreeHGlobal(ptr); 

     return arr; 
    } 

    public static T BytesToSturct<T>(byte[] buffer) where T : struct 
    { 
     int size = Marshal.SizeOf(typeof(T)); 

     IntPtr ptr = Marshal.AllocHGlobal(size); 
     Marshal.Copy(buffer, 0, ptr, size); 
     T obj = (T)Marshal.PtrToStructure(ptr, typeof(T)); 
     Marshal.FreeHGlobal(ptr); 

     return obj; 
    } 

} 

나는 제거합니다.

무엇이 문제입니까?

+0

** 통합 프로그램 종료 ** 그게 무슨 뜻입니까? 동결? – Programmer

+0

라인을 디버그하여 프로그램이 실패 할 수 있습니까? 종료 됨은 무엇을 의미합니까? Crash, ErrorMessage, Frezze? – Master117

+0

"유니티 에디터가 작동을 멈췄다"라는 메시지가 뜨고 유니티 프로그램이 갑자기 나왔다가 데스크탑으로 간다. (유니티 프로그램을 다시 열어야한다.) 로그 메시지를 확인할 수 없다. –

답변

1

메시지가 팝업 및 단합 프로그램 이 갑자기 종료되고 (내가 화합 프로그램을 다시해야합니다) 바탕 화면으로 이동한다 "유니티 에디터는 작동이 중지되었습니다"그래서 내가 내가 발견 할 수 MSG에게

를 기록 확인할 수 없습니다 귀하의 코드에 몇 가지 문제가 있습니다.

. Thread없이 synchronous socket을 사용하고 있습니다. synchronous socket을 사용하는 경우 Thread과 함께 사용해야합니다. 그렇지 않으면 클라이언트 연결, 서버 연결 또는 클라이언트로부터의 수신을 기다리는 동안 Unity가 고정됩니다.

다른 해결책은 asynchronous socket을 사용하는 것입니다. 사용하려면 Thread이 필요하지 않습니다.

. while (totalByteRcvd < buffersize). 이렇게하면 totalByteRcvd >= buffersize까지 즉시 Unity가 동결되고 그 전에는 netStream.Read이 반환되어야하지만이 문제는 # 1의 문제로 인해 곧 발생하지 않습니다.

receive(); 

void receive() 
{ 
    System.Threading.Thread socketThread = new System.Threading.Thread(recvPacket); 
    socketThread.Start(); 
} 

이것은 당신의 동결 문제를 해결해야합니다

그래서 무효 기능이 같은 전화를하여 recvPacket() 기능을합니다. 그래도 작동하지 않으면 코드에 다른 문제가 있습니다. here의 작동중인 서버 소켓 코드를 사용하십시오. 단순히 클라이언트 코드로 변환 할 수 있습니다.

+0

Unity 5.3에서이 기능이 작동합니까? –

+0

@ 마크 무엇이 나를 위해 일 했는가? 내가 링크 한 코드? – Programmer

+0

예. 기본적으로 유니티의 마샬링 클래스와 관련된 것은 무엇입니까? –