让人头疼的Socket断开Disconnect方法,前面是基于SocketAsyncEventArgs的操作。
--------------------编程问答-------------------- 代码还没完,继续贴代码。--------------------编程问答-------------------- 上面的Send函数中,将
/// <summary>
/// 发送数据,将来源数据发送到已连接的服务端
/// </summary>
/// <param name="sendBytes">要发送的数据</param>
public void Send(byte[] sendBytes)
{
if (!m_bIsConnect)
throw new Exception("Don't Connected");
if (!m_socket.Connected)
throw new Exception("Don't Connected");
if(m_writeEventArg.Buffer == null)
throw new ArgumentNullException("buffer","缓冲区尚未设置");
if (sendBytes.Length > m_writeEventArg.Count)
throw new ArgumentOutOfRangeException("sendBytes", "发送字节数超出缓冲区");
for (int i = 0; i < sendBytes.Length; i++)
{
m_writeEventArg.Buffer[i + m_writeEventArg.Offset] = sendBytes[i];
}
m_writeEventArg.SendPacketsSendSize = sendBytes.Length;
bool willRaiseEvent = m_socket.SendAsync(m_writeEventArg);
if (!willRaiseEvent)
{
ProcessSend(m_writeEventArg);
}
}
private void ProcessSend(SocketAsyncEventArgs m_writeEventArg)
{
// throw new NotImplementedException();
// 如果发送失败,报到断开连接
if (m_writeEventArg.SocketError != SocketError.Success)
{
Disconnect();
}
}
public event ConnectionEventHandler Received;
public event ConnectionEventHandler Connected;
public event ConnectionEventHandler Disconnected;
public event ConnectionEventHandler OutPutString;
/// <summary>
/// 触发接收事件,实际上参数是SocketAsyncEventArgs,包含了所有的数据和节点信息
/// </summary>
/// <param name="e"></param>
protected void OnReceive(EventArgs e)
{
if (Received != null)
{
SocketAsyncEventArgs saea = e as SocketAsyncEventArgs;
string text = "";
if (saea.RemoteEndPoint != null)
{
text = ((IPEndPoint)saea.RemoteEndPoint).Address.ToString() + ":"
+ ((IPEndPoint)saea.RemoteEndPoint).Port.ToString();
}
byte[] recvBytes = new byte[saea.BytesTransferred];
for (int i = 0; i < recvBytes.Length; i++)
{
recvBytes[i] = saea.Buffer[i + saea.Offset];
}
Received(this, new ConnectionEventArgs(text, this.m_key.ToString(), recvBytes));
}
}
/// <summary>
/// 触发连接完成事件,该事件包含连接的远程地址和为本地分配的Key
/// </summary>
/// <param name="e">来自ProcessConnect的参数</param>
protected void OnConnect(EventArgs e)
{
if (Connected != null)
{
SocketAsyncEventArgs saEArg = e as SocketAsyncEventArgs;
string ip = "";
if (saEArg.RemoteEndPoint != null)
{
ip = ((IPEndPoint)saEArg.RemoteEndPoint).Address.ToString() + ":"
+ ((IPEndPoint)saEArg.RemoteEndPoint).Port.ToString();
}
Connected(this, new ConnectionEventArgs(ip, this.m_key.ToString(), null));
}
}
protected void OnDisconnect(EventArgs e)
{
if (Disconnected != null)
Disconnected(this, e);
}
protected void OnOutPutString(EventArgs e)
{
if (OutPutString != null)
OutPutString(this, e);
}
}
public class ConnectionEventArgs : EventArgs
{
// 输出字符串
public string Text { get; private set; }
// 事件来源者的Key
public string Key { get; private set; }
// 事件需要输出的字节
public byte[] Bytes { get; private set; }
public ConnectionEventArgs(string text, string key, byte[] bytes)
{
Text = text;
Key = key;
Bytes = bytes;
}
}
m_writeEventArg.SendPacketsSendSize = sendBytes.Length;
这句改成下面这句。
m_writeEventArg.SetBuffer(m_writeEventArg.Offset, sendBytes.Length); --------------------编程问答-------------------- 附上命令行模式的测试程序代码:
--------------------编程问答-------------------- setbuffer的函数实现呢?没有吗? --------------------编程问答-------------------- 在用使用SocketAsyncEventArgs ,关注中! --------------------编程问答-------------------- 重用没有什么必要,百分之九十九点九的开销都用掉了。。不在乎那一点。。
class Program
{
static void Main(string[] args)
{
new MainClass().Run();
}
}
class MainClass
{
ITCPAsyncClient asyncClient;
public MainClass()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("164.70.6.63"),9002);
asyncClient = new TCPAsyncClient(ip, 1);
asyncClient.Connected += new ConnectionEventHandler(DoEventThings);
asyncClient.Received += new ConnectionEventHandler(DoEventThings);
asyncClient.Disconnected +=new ConnectionEventHandler(DoEventThings);
asyncClient.OutPutString += new ConnectionEventHandler(DoEventThings);
byte[] buffer = new byte[1024];
asyncClient.SetBuffer(buffer, 0, 1024);
}
void DoEventThings(object sender, EventArgs e)
{
//throw new NotImplementedException();
string show = "";
ConnectionEventArgs cnEArg = e as ConnectionEventArgs;
if (cnEArg.Text != null)
show += cnEArg.Text + " ";
if (cnEArg.Key != null)
show += cnEArg.Key + ":";
if(cnEArg.Bytes!= null)
for (int i = 0; i < cnEArg.Bytes.Length; i++)
{
show += cnEArg.Bytes[i].ToString("X2") + " ";
}
Console.WriteLine(show);
}
public void Run()
{
asyncClient.Connect();
string input = "";
while (true)
{
Console.WriteLine("输入要发送的数据或者输入d回车断开连接");
input = Console.ReadLine();
if (input.ToLower() == "d")
{
asyncClient.Disconnect();
Console.WriteLine("看到断开提示后,输入c重新连接或者q退出程序");
input = Console.ReadLine();
if (input.ToLower() == "c")
{
asyncClient.Connect();
continue;
}
else
{
break;
}
}
else
{
if (input.Length == 0)
continue;
asyncClient.Send(Encoding.Default.GetBytes(input));
}
}
}
}
补充:.NET技术 , .NET Framework