📄 serversocket.cs
字号:
/*
NotifyCommand enum
--
List of socket notification commands.
ServerSocket class
--
Uses synchronous sockets to connect and receive data from the client.
Creates a worker thread that handles all socket communications. Sends
an acknowledgment to the client after data has been received. 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.Drawing;
using System.Diagnostics;
using Common;
namespace DesktopSignature
{
/// <summary>
/// Socket notification commands.
/// </summary>
public enum NotifyCommand
{
Listen,
Connected,
Disconnected,
ReceivedData
}
/// <summary>
/// Listens and connects to socket connection request. Receives data
/// from socket and sends back an acknowledgement. Creates worker
/// thread so UI is not blocked.
/// </summary>
public class ServerSocket
{
int _port;
Socket _listen;
Socket _socket;
// used for socket notifications
public delegate void NotifyEventHandler(NotifyCommand command, object data);
public event NotifyEventHandler Notify;
public ServerSocket()
{
}
/// <summary>
/// Start listening for client socket connection.
/// </summary>
public void Start(int portNumber)
{
// save port number
_port = portNumber;
// make sure stop if currently connected
Stop();
// create a new thread that handle client connection
ThreadPool.QueueUserWorkItem(new WaitCallback(Listen));
}
/// <summary>
/// Shutdown the socket.
/// </summary>
public void Stop()
{
if (_socket != null)
{
if (_socket.Connected)
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
_socket = null;
RaiseNotifyEvent(NotifyCommand.Disconnected, null);
}
if (_listen != null)
{
_listen.Close();
_listen = null;
}
}
/// <summary>
/// Restart the socket.
/// </summary>
public void Restart()
{
Stop();
Start(_port);
}
/// <summary>
/// Main socket thread that does all of the work. Listens for client
/// socket connection. Connects to the client when detects connection and
/// reads data sent over socket. Raises an notification event when socket
/// operations occur.
/// </summary>
private void Listen(object state)
{
// establish connection with client
IPHostEntry ipHost = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddress, _port);
try
{
// listen for client connection
_listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_listen.Blocking = true;
_listen.Bind(endPoint);
_listen.Listen(0);
// listening
RaiseNotifyEvent(NotifyCommand.Listen, endPoint.Address.ToString());
// block here until establish a connection
_socket = _listen.Accept();
// we connected with a client, shutdown the listen socket
// so we won't connect with another client
_listen.Close();
// connected
RaiseNotifyEvent(NotifyCommand.Connected,
_socket.RemoteEndPoint.ToString());
// sit in this loop until connection is broken
// handle client commands and send back response
bool bListen = true;
while (bListen)
{
// reset everything for the next read message
bool bReadMessage = true;
int bytesRead = 0;
int totalBytes = 0;
// hold incoming data
byte[] buf = new byte[1024];
MemoryStream streamRead = new MemoryStream();
while (bReadMessage)
{
// loop that reads incoming message
// buf is temp holder and the MemoryStream
// contains all of the bits
bytesRead = _socket.Receive(buf);
if (bytesRead > 0)
{
streamRead.Write(buf, 0, bytesRead);
bReadMessage = !Network.CheckForTerminator(streamRead.ToArray());
totalBytes += bytesRead;
}
else
{
// client disconnected
Restart();
throw (new Exception("Client disconnected."));
}
}
// done reading incoming message, now process the command
ProcessCommand(streamRead);
streamRead.Close();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
/// <summary>
/// Process the command that was received from the client.
/// </summary>
private void ProcessCommand(MemoryStream streamRead)
{
try
{
// remove message terminator
streamRead.SetLength(streamRead.Length - Network.Terminator.Length);
// get the command data
streamRead.Position = 0;
byte[] data = streamRead.ToArray();
RaiseNotifyEvent(NotifyCommand.ReceivedData, data);
// send back ack that signature was received
byte[] result = new byte[1];
result[0] = 1;
_socket.Send(result, 0, result.Length, SocketFlags.None);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
/// <summary>
/// Raise notification event.
/// </summary>
private void RaiseNotifyEvent(NotifyCommand command, object data)
{
if (this.Notify != null)
Notify(command, data);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -