Асинхронные сокеты

Сеть в Unity3D

Асинхронные сокеты

Сообщение Ferz 27 июл 2009, 10:50

Решил прикрутить к сцене Юнити асинхронные сокеты. Получился следующий класс ServerListener

Код: Выделить всё
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, а при повтороном - выносит едитор.
Вопрос заключается в том, почему так происходит. Насколько я сам могу предполагать, скорее всего так получатеся из-за не закрытых вовремя сокетов. Но где и когда их нужно закрывать?
Ferz
UNец
 
Сообщения: 35
Зарегистрирован: 25 июл 2009, 00:20

Re: Асинхронные сокеты

Сообщение Neodrop 27 июл 2009, 15:45

А вы используете потоки (не глядел внимательно код) ?
Вы позаботились о их закрытии при закрытии приложения? :-?
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Асинхронные сокеты

Сообщение Ferz 28 июл 2009, 20:42

Нет, вот потоки я не трогал - думал, что оно как нибудь само разберется, как в обычных примерчиках по асинхронным сокетам.

В процессе поиска информации наткнулся на замечательную вещь для взаимодействия через сокеты, которая уже заточена под юнити, и более того, заработала даже у меня))
http://www.unifycommunity.com/wiki/inde ... workCursor

П.С. При использовании не забывайте разрешать приложению работу в фоновом режиме
Application.runInBackground = true;
Ferz
UNец
 
Сообщения: 35
Зарегистрирован: 25 июл 2009, 00:20

Re: Асинхронные сокеты

Сообщение Multirezonator 19 мар 2010, 07:46

Та же самая проблема у меня была пока сокеты не начал закрывать, при закрытии приложения. У Вас закрытия закомментированны:

Код: Выделить всё
void OnApplicationQuit ()
   {
      //listenSocket.Close();
      //serverSocket.Shutdown(SocketShutdown.Both);
        //serverSocket.Close();
   }


порпробуйте раскомментировать для начала, и нужно для всех объектов Socket обязательно вызвать Socket.Close()
Скрытый текст:



Аватара пользователя
Multirezonator
UNITрон
 
Сообщения: 248
Зарегистрирован: 15 фев 2010, 16:12
Откуда: Украина, Луганск
  • Сайт


Вернуться в Сеть

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2