Saya bekerja dengan Unity dan mengalami masalah dengan BeginConnect dan metode asinkron lainnya dari soket.
Ada sesuatu yang tidak saya mengerti tetapi contoh kode sebelumnya tidak berfungsi untuk saya.
Jadi saya menulis kode ini untuk membuatnya berfungsi. Saya mengujinya di jaringan adhoc dengan android dan pc, juga di lokal di komputer saya. Semoga bisa membantu.
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System;
using System.Diagnostics;
class ConnexionParameter : Guardian
{
public TcpClient client;
public string address;
public int port;
public Thread principale;
public Thread thisthread = null;
public int timeout;
private EventWaitHandle wh = new AutoResetEvent(false);
public ConnexionParameter(TcpClient client, string address, int port, int timeout, Thread principale)
{
this.client = client;
this.address = address;
this.port = port;
this.principale = principale;
this.timeout = timeout;
thisthread = new Thread(Connect);
}
public void Connect()
{
WatchDog.Start(timeout, this);
try
{
client.Connect(IPAddress.Parse(address), port);
}
catch (Exception)
{
UnityEngine.Debug.LogWarning("Unable to connect service (Training mode? Or not running?)");
}
OnTimeOver();
//principale.Resume();
}
public bool IsConnected = true;
public void OnTimeOver()
{
try
{
if (!client.Connected)
{
/*there is the trick. The abort method from thread doesn't
make the connection stop immediately(I think it's because it rise an exception
that make time to stop). Instead I close the socket while it's trying to
connect , that make the connection method return faster*/
IsConnected = false;
client.Close();
}
wh.Set();
}
catch(Exception)
{
UnityEngine.Debug.LogWarning("Connexion already closed, or forcing connexion thread to end. Ignore.");
}
}
public void Start()
{
thisthread.Start();
wh.WaitOne();
//principale.Suspend();
}
public bool Get()
{
Start();
return IsConnected;
}
}
public static class Connexion
{
public static bool Connect(this TcpClient client, string address, int port, int timeout)
{
ConnexionParameter cp = new ConnexionParameter(client, address, port, timeout, Thread.CurrentThread);
return cp.Get();
}
//http://stackoverflow.com/questions/19653588/timeout-at-acceptsocket
public static Socket AcceptSocket(this TcpListener tcpListener, int timeoutms, int pollInterval = 10)
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutms);
var stopWatch = new Stopwatch();
stopWatch.Start();
while (stopWatch.Elapsed < timeout)
{
if (tcpListener.Pending())
return tcpListener.AcceptSocket();
Thread.Sleep(pollInterval);
}
return null;
}
}
dan ada pengawas yang sangat sederhana di C # untuk membuatnya bekerja:
using System.Threading;
public interface Guardian
{
void OnTimeOver();
}
public class WatchDog {
int m_iMs;
Guardian m_guardian;
public WatchDog(int a_iMs, Guardian a_guardian)
{
m_iMs = a_iMs;
m_guardian = a_guardian;
Thread thread = new Thread(body);
thread.Start(this);
}
private void body(object o)
{
WatchDog watchdog = (WatchDog)o;
Thread.Sleep(watchdog.m_iMs);
watchdog.m_guardian.OnTimeOver();
}
public static void Start(int a_iMs, Guardian a_guardian)
{
new WatchDog(a_iMs, a_guardian);
}
}