1.客户端
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
namespace SocketIM
{
public class AsynchronousClient
{
private const int port = 11000;
private static ManualResetEvent readyconnectDone = new ManualResetEvent(false);
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
// The response from the remote device.
private static String response = String.Empty;
public static void StartClient()
{
// Connect to a remote device.
try
{
IPAddress ipAddress = IPAddress.Parse(Utility.ConfigManager.GetConfig("IMIP"));
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
readyconnectDone.Set();
connectDone.WaitOne();
// Send test data to the remote device.
Send(client, "Clear ETL Cache");
sendDone.WaitOne();
}
catch (Exception e)
{
Holworth.Utility.Logger.Fatal(e);
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
readyconnectDone.WaitOne();
connectDone.Set();
}
catch (Exception e)
{
Holworth.Utility.Logger.Fatal(e);
}
}
private static void Send(Socket client, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int bytesSent = client.EndSend(ar);
client.Shutdown(SocketShutdown.Both);
client.Close();
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
sendDone.Set();
}
catch (Exception e)
{
Holworth.Utility.Logger.Fatal(e);
}
}
}
}
2.服务端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SocketIM
{
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
// State object for reading client data asynchronously
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousSocketListener
{
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public AsynchronousSocketListener()
{
}
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local
//endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
public static IIMCallBack IMCallBack
{
get;
set;
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
if (IMCallBack != null)
{
IMCallBack.IMCallBack(state.buffer);
}
}
}
}
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
if (IMCallBack != null)
{
IMCallBack.IMCallBack(state.buffer);
}
}
}
3.TcpClient
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
/// <summary>
/// TcpClientWithTimeout 用来设置一个带连接超时功能的类
/// 使用者可以设置毫秒级的等待超时时间 (1000=1second)
/// 例如:
/// TcpClient connection = new TcpClientWithTimeout('127.0.0.1',80,1000).Connect();
/// </summary>
namespace SocketIM {
public class TcpClientWithTimeout
{
protected string _hostname;
protected int _port;
protected int _timeout_milliseconds;
protected TcpClient connection;
protected bool connected;
protected Exception exception;
public TcpClientWithTimeout(string hostname, int port, int timeout_milliseconds)
{
_hostname = hostname;
_port = port;
_timeout_milliseconds = timeout_milliseconds;
}
public static void SendDefaultMessage()
{
SendDefaultMessage(string.Empty, "1","");
}
public static void SendDefaultMessage(string data,string messageTpe,string ip)
{
if (string.IsNullOrEmpty(ip))
{
ip = Utility.ConfigManager.GetConfig("IMIP");
}
int port = 11000;
TcpClientWithTimeout tcp = new SocketIM.TcpClientWithTimeout(ip, port, 3000);
try
{
var connection = tcp.Connect();
NetworkStream stream = connection.GetStream();
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("MessageType", messageTpe);
dic.Add("Data", data);
var s = Newtonsoft.Json.JsonConvert.SerializeObject(dic);
// Send 10 bytes
byte[] to_send = Encoding.UTF8.GetBytes(s);
stream.Write(to_send, 0, to_send.Length);
// Receive 10 bytes
byte[] readbuf = new byte[10]; // you must allocate space first
stream.ReadTimeout = 10000; // 10 second timeout on the read
stream.Read(readbuf, 0, 10); // read
// Disconnect nicely
stream.Close(); // workaround for a .net bug: http://support.microsoft.com/kb/821625
connection.Close();
}
catch (Exception ex)
{
Holworth.Utility.Logger.Fatal(ex);
}
}
public TcpClient Connect()
{
// kick off the thread that tries to connect
connected = false;
exception = null;
Thread thread = new Thread(new ThreadStart(BeginConnect));
thread.IsBackground = true; // 作为后台线程处理
// 不会占用机器太长的时间
thread.Start();
// 等待如下的时间
thread.Join(_timeout_milliseconds);
if (connected == true)
{
// 如果成功就返回TcpClient对象
thread.Abort();
return connection;
}
if (exception != null)
{
// 如果失败就抛出错误
thread.Abort();
throw exception;
}
else
{
// 同样地抛出错误
thread.Abort();
string message = string.Format("TcpClient connection to {0}:{1} timed out",
_hostname, _port);
throw new TimeoutException(message);
}
}
protected void BeginConnect()
{
try
{
connection = new TcpClient(_hostname, _port);
// 标记成功,返回调用者
connected = true;
}
catch (Exception ex)
{
// 标记失败
exception = ex;
}
}
}
}