110,566
社区成员
发帖
与我相关
我的任务
分享
class Client
{
public bool Connet(string ip, string port)
{
try
{
m_bAvailable = false;
m_dataBuffer = new byte[512];
IPAddress destinationAddr = null; // IP Address of server to connect to
int destinationPort = 0; // Port number of server
destinationAddr = IPAddress.Parse(ip);
destinationPort = int.Parse(port);
m_receiveEventArgs = new SocketAsyncEventArgs();
m_sendEventArgs = new SocketAsyncEventArgs();
// Create a socket and connect to the server
Socket sock = new Socket(destinationAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
m_receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(SocketEventArg_Completed);
m_receiveEventArgs.RemoteEndPoint = new IPEndPoint(destinationAddr, destinationPort);
m_receiveEventArgs.UserToken = sock;
m_sendEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(SocketEventArg_Completed);
m_sendEventArgs.RemoteEndPoint = new IPEndPoint(destinationAddr, destinationPort);
m_sendEventArgs.UserToken = sock;
sock.ConnectAsync(m_receiveEventArgs);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return false;
}
return true;
}
public bool Receive()
{
try
{
//Read data sent from the server
Socket sock = m_receiveEventArgs.UserToken as Socket;
Console.WriteLine("calling ReceiveAsync");
bool willRaiseEvent = sock.ReceiveAsync(m_receiveEventArgs);
if (!willRaiseEvent)
{
ProcessReceive(m_receiveEventArgs);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return false;
}
return true;
}
public bool IsConnect
{
get
{
return m_bAvailable;
}
}
public bool SendToServer(byte[] buffer)
{
// Send 'Hello World' to the server
//byte[] buffer = Encoding.UTF8.GetBytes("Hello World");
//m_sendEventArgs
Console.WriteLine("Send to server: {0}", Encoding.UTF8.GetString(buffer));
m_receiveEventArgs.SetBuffer(buffer, 0, buffer.Length);
Socket sock = m_receiveEventArgs.UserToken as Socket;
//【疑惑】当执行过ReceiveAsync以后且没有数据被接收(处于等待接收状态)
// 如果执行SendAsync会遇到InvalidOperation异常
bool willRaiseEvent = sock.SendAsync(m_receiveEventArgs);
if (!willRaiseEvent)
{
ProcessSend(m_receiveEventArgs);
}
return true;
}
//心跳检测
public void Ping()
{
// Send 'Hello World' to the server
byte[] buffer = Encoding.UTF8.GetBytes("Hello World");
SendToServer(buffer);
}
protected void ReceiveFromServer(byte[] buffer)
{
}
/// <summary>
/// A single callback is used for all socket operations. This method forwards execution on to the correct handler
/// based on the type of completed operation
/// </summary>
private void SocketEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
ProcessConnect(e);
break;
case SocketAsyncOperation.Receive:
ProcessReceive(e);
break;
case SocketAsyncOperation.Send:
ProcessSend(e);
break;
default:
throw new Exception("Invalid operation completed");
}
}
/// <summary>
/// Called when a ConnectAsync operation completes
/// </summary>
private void ProcessConnect(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
//m_bAvailable = true;
Console.WriteLine("Successfully connected to the server");
// 【疑惑】为什么在这里ReceiveAsync就会遭遇NullReferenceException,而SendAsync就没问题?
//Receive();// first Receive
Ping();
}
else
{
throw new SocketException((int)e.SocketError);
}
}
/// <summary>
/// Called when a ReceiveAsync operation completes
/// </summary>
private void ProcessReceive(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Console.WriteLine("Received from server: {0}", Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred));
//粘包等处理逻辑
// TODO:
Receive();// for the next coming data
}
else
{
throw new SocketException((int)e.SocketError);
}
}
/// <summary>
/// Called when a SendAsync operation completes
/// </summary>
private void ProcessSend(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
if (!m_bAvailable)
{
Receive();//第一次发送数据成功后可以开始准备接受数据。
}
m_bAvailable = true;
}
else
{
m_bAvailable = false;
// Disconnect from the server
Socket sock = e.UserToken as Socket;
sock.Shutdown(SocketShutdown.Send);
sock.Close();
//clientDone.Set();
}
}
private SocketAsyncEventArgs m_receiveEventArgs;
private SocketAsyncEventArgs m_sendEventArgs;
private bool m_bAvailable;
private byte[] m_dataBuffer;
}