📄 clientsocket.cs
字号:
/*
NotifyCommand enum
--
List of socket notification commands.
ClientSocket class
--
Connects and sends data over TCP sockets. Uses async sockets so a delegate
method is called when the socket command completes. Raises an Notify event
when socket operations complete and passes any associated data with the event.
*/
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Text;
using System.Configuration;
using System.Collections;
using System.Diagnostics;
using Common;
namespace PocketSignature
{
/// <summary>
/// Socket notification commands.
/// </summary>
public enum NotifyCommand
{
Connected,
SentData,
ReceivedData,
Error
}
/// <summary>
/// Use async sockets to connect, send and receive data over TCP sockets.
/// </summary>
public class ClientSocket
{
// notification event
public delegate void NotifyEventHandler(NotifyCommand command, object data);
public event NotifyEventHandler Notify;
// socket that exchanges information with server
Socket _socket;
// holds information sent back from server
byte[] _readBuffer = new byte[1];
// used to synchronize the shutdown process, terminate
// any pending async calls before Disconnect returns
ManualResetEvent _asyncEvent = new ManualResetEvent(true);
bool _disconnecting = false;
// async callbacks
AsyncCallback _connectCallback, _sendCallback, _receiveCallback;
/// <summary>
/// Returns true if the socket is connected to the server. The property
/// Socket.Connected does not always indicate if the socket is currently
/// connected, this polls the socket to determine the latest connection state.
/// </summary>
public bool Connected
{
get
{
// return right away if have not created socket
if (_socket == null)
return false;
// the socket is not connected if the Connected property is false
if (!_socket.Connected)
return false;
// there is no guarantee that the socket is connected even if the
// Connected property is true
try
{
// poll for error to see if socket is connected
return !_socket.Poll(1, SelectMode.SelectError);
}
catch
{
return false;
}
}
}
public ClientSocket()
{
// hookup async callbacks
_connectCallback = new AsyncCallback(ConnectCallback);
_sendCallback = new AsyncCallback(SendCallback);
_receiveCallback = new AsyncCallback(ReceiveCallback);
}
/// <summary>
/// Connect to the specified address and port number.
/// </summary>
public void Connect(string address, int port)
{
// make sure disconnected
Disconnect();
// connect to the server
IPAddress ipAddress = IPAddress.Parse(address);
IPEndPoint endPoint = new IPEndPoint(ipAddress, port);
_socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
_asyncEvent.Reset();
_socket.BeginConnect(endPoint, _connectCallback, null);
}
/// <summary>
/// Disconnect from the server.
/// </summary>
public void Disconnect()
{
// return right away if have not created socket
if (_socket == null)
return;
// set this flag so we don't raise any error notification
// events when disconnecting
_disconnecting = true;
try
{
// first, shutdown the socket
_socket.Shutdown(SocketShutdown.Both);
}
catch {}
try
{
// next, close the socket which terminates any pending
// async operations
_socket.Close();
// wait for any async operations to complete
_asyncEvent.WaitOne();
}
catch {}
_disconnecting = false;
}
/// <summary>
/// Send data to the server.
/// </summary>
public void Send(byte[] data)
{
// send the data
_socket.BeginSend(data, 0, data.Length,
SocketFlags.None, null, null);
// send the terminator
_asyncEvent.Reset();
_socket.BeginSend(Network.TerminatorBytes, 0,
Network.TerminatorBytes.Length,
SocketFlags.None, _sendCallback, true);
}
/// <summary>
/// Read data from server.
/// </summary>
public void Receive()
{
_asyncEvent.Reset();
_socket.BeginReceive(_readBuffer, 0, _readBuffer.Length,
SocketFlags.None, _receiveCallback, null);
}
/// <summary>
/// Raise notification event.
/// </summary>
private void RaiseNotifyEvent(NotifyCommand command, object data)
{
// the async operation has completed
_asyncEvent.Set();
// don't raise notification events when disconnecting
if ((this.Notify != null) && !_disconnecting)
Notify(command, data);
}
//
// async callbacks
//
private void ConnectCallback(IAsyncResult ar)
{
try
{
// pass connection status with event
_socket.EndConnect(ar);
RaiseNotifyEvent(NotifyCommand.Connected, this.Connected);
}
catch (Exception ex)
{
RaiseNotifyEvent(NotifyCommand.Error, ex.Message);
}
}
private void SendCallback(IAsyncResult ar)
{
try
{
_socket.EndSend(ar);
RaiseNotifyEvent(NotifyCommand.SentData, null);
}
catch (Exception ex)
{
RaiseNotifyEvent(NotifyCommand.Error, ex.Message);
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
_socket.EndReceive(ar);
// the server sends an acknowledgment back
// that is stored in the read buffer
RaiseNotifyEvent(NotifyCommand.ReceivedData,
_readBuffer[0] == 1 ? true : false);
}
catch (Exception ex)
{
RaiseNotifyEvent(NotifyCommand.Error, ex.Message);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -