- Код: Выделить всё
using UnityEngine;
using System.Collections;
using System;
using System.Threading;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
public class ServerListener : MonoBehaviour {
public IAsyncResult asyncAccept;
public static IAsyncResult asyncReceive;
public static Socket listenSocket;
public static Socket serverSocket;
public static string recivedText;
internal class StateObject
{
internal byte[] sBuffer;
internal Socket sSocket;
internal int sBufferSize;
internal StateObject(int size, Socket sock)
{
sBufferSize = size;
sBuffer = new byte[size];
sSocket = sock;
}
}
// Use this for initialization
void Start ()
{
recivedText = "";
IPAddress ipAddress = IPAddress.Parse("127.0.01");
//Dns.Resolve(Dns.GetHostName()).AddressList[0];
IPEndPoint ipEndpoint =
new IPEndPoint(ipAddress, 12800);
listenSocket =
new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
listenSocket.Bind(ipEndpoint);
listenSocket.Listen(1);
asyncAccept = listenSocket.BeginAccept(new AsyncCallback(ServerListener.acceptCallback),
listenSocket);
// could call listenSocket.EndAccept(asyncAccept) here
// instead of in the callback method, but since
// EndAccept blocks, the behavior would be similar to
// calling the synchronous Accept method
Debug.Log("Connection in progress.");
}
// Update is called once per frame
void Update () {
//Debug.Log(asyncAccept.IsCompleted);
if (asyncAccept.IsCompleted)
{
Debug.Log("Acsepting is completed.");
asyncAccept = listenSocket.BeginAccept(new AsyncCallback(ServerListener.acceptCallback),
listenSocket);
}
else
{
//Debug.Log(".");
}
}
public static void acceptCallback(IAsyncResult asyncAccept)
{
listenSocket = (Socket)asyncAccept.AsyncState;
serverSocket = listenSocket.EndAccept(asyncAccept);
// arriving here means the operation completed
// (asyncAccept.IsCompleted = true) but not
// necessarily successfully
if (serverSocket.Connected == false)
{
Debug.Log(".server is not connected.");
return;
}
else Debug.Log(".server is connected.");
//listenSocket.Close();
StateObject stateObject = new StateObject(16, serverSocket);
// this call passes the StateObject because it
// needs to pass the buffer as well as the socket
asyncReceive = serverSocket.BeginReceive(
stateObject.sBuffer,
0,
stateObject.sBuffer.Length,
SocketFlags.None,
new AsyncCallback(receiveCallback),
stateObject);
Debug.Log("Receiving data.");
}
public static void
receiveCallback(IAsyncResult asyncReceive)
{
StateObject stateObject = (StateObject)asyncReceive.AsyncState;
int bytesReceived = stateObject.sSocket.EndReceive(asyncReceive);
recivedText += Encoding.ASCII.GetString(stateObject.sBuffer);
//MemoryStream mems = new MemoryStream(stateObject.sBuffer,0,stateObject.sBufferSize,true,true);
//ReceivedObject robj = ReceivedObject.Load(new BinaryReader(mems));
//SocketCommands.ApplyCommand(robj);
byte[] sendBuffer = Encoding.ASCII.GetBytes("Goodbye");
IAsyncResult asyncSend = stateObject.sSocket.BeginSend(
sendBuffer,
0,
sendBuffer.Length,
SocketFlags.None,
new AsyncCallback(sendCallback),
stateObject.sSocket);
Debug.Log("Sending response.");
}
public static void sendCallback(IAsyncResult asyncSend)
{
serverSocket = (Socket)asyncSend.AsyncState;
int bytesSent = serverSocket.EndSend(asyncSend);
}
void OnApplicationQuit ()
{
//listenSocket.Close();
//serverSocket.Shutdown(SocketShutdown.Both);
//serverSocket.Close();
}
}
Результаты егоработы таковы:
дома в режиме Editor оно работает хорошо, и даже, принимает текстовую строку. В режиме созданного проекта оно тоже работет, но при закрытии приложения ругается на то, что память не может быть read.
На работе эта штука при первом запуске в режиме едитора подвешивает GUI, а при повтороном - выносит едитор.
Вопрос заключается в том, почему так происходит. Насколько я сам могу предполагать, скорее всего так получатеся из-за не закрытых вовремя сокетов. Но где и когда их нужно закрывать?