📄 chatclass.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Threading;
using System.Drawing;
using System.Diagnostics;
using System.Collections;
using System.IO;
using System.Xml;
namespace Th.ChatLib
{
public delegate void DelegateAfterReceive(ReceiveDataEventArgs e);
public delegate void DelegateAfterSend(SendStateEventArgs e);
public delegate void DelegateRemoteStateChange(ServerStateEventArgs e);
public class ChatClass
{
private class ChatHost
{
private IPAddress m_IP;
public IPAddress IP
{
get { return m_IP; }
}
public string IPString
{
get { return m_IP.ToString(); }
}
private int m_LastRevTick;
public int LastRevTick
{
get { return m_LastRevTick; }
set { m_LastRevTick = value; }
}
public ChatHost(IPAddress ip, int lastRevTick)
{
m_IP = ip;
m_LastRevTick = lastRevTick;
}
}
private ArrayList m_ChatHostList = new ArrayList();
private ChatHost RegisterChatHost(IPAddress ip)
{
foreach (ChatHost chatHost in m_ChatHostList)
{
if (chatHost.IPString == ip.ToString())
{
return chatHost;
}
}
ChatHost host = new ChatHost(ip, 0);
m_ChatHostList.Add(host);
return host;
}
private ChatHost GetChatHost(IPAddress ip)
{
foreach (ChatHost host in m_ChatHostList)
{
if (host.IPString == ip.ToString())
{
return host;
}
}
return null;
}
/// <summary>
/// 发送和接收的超时等待时间
/// </summary>
private const int SEND_RECV_TIMEOUT = 100;
private const int LOCAL_PORT = 51533;
/// <summary>
/// 版本号
/// </summary>
private const byte MSG_VER = 1;
/// <summary>
/// 聊天信息
/// </summary>
private const byte MSG_CHAT = 1;
/// <summary>
/// 上线通知
/// </summary>
private const byte MSG_UPLINE = 2;
/// <summary>
/// 下线通知
/// </summary>
private const byte MSG_OFFLINE = 3;
/// <summary>
/// 信息接收确认
/// </summary>
private const byte MSG_INCEPT = 4;
/// <summary>
/// 上线通知回复
/// </summary>
private const byte MSG_UPLINE_REVERT = 5;
private SendStateEventArgs m_LastSendState = new SendStateEventArgs(false);
public SendStateEventArgs LastSendState
{
get { return m_LastSendState; }
}
public event DelegateAfterReceive AfterReceive;
public event DelegateAfterSend AfterSend;
public event DelegateRemoteStateChange ServerStateChange;
private void FireServerStateChangeEvent(ServerStateEventArgs e)
{
if (ServerStateChange != null) ServerStateChange(e);
}
private void FireAfterReceiveEvent(ReceiveDataEventArgs e)
{
if (AfterReceive != null) AfterReceive(e);
}
private void FireAfterSendEvent()
{
if (AfterSend != null) AfterSend(m_LastSendState);
}
private UdpClient m_UdpClient;
private string m_LocalHostName;
public string LocalHostName
{
get { return m_LocalHostName; }
}
private IPAddress m_LocalHostIPAddress;
public IPAddress LocalHostIPAddress
{
get { return m_LocalHostIPAddress; }
}
private string m_LogPath;
private FileStream m_ChatFile;
private StreamWriter m_ChatWriter;
public ChatClass(string logPath)
{
m_LogPath = logPath;
m_LocalHostName = Dns.GetHostName();
m_LocalHostIPAddress = Dns.GetHostAddresses(m_LocalHostName)[0];
}
public void StartWork()
{
Directory.CreateDirectory(m_LogPath);
m_ChatFile = new FileStream(Path.Combine(m_LogPath, string.Format("{0:000}-{1:00}-{2:00}.txt", DateTime.Now.Year,
DateTime.Now.Month, DateTime.Now.Day)), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
m_ChatFile.Seek(0, SeekOrigin.End);
m_ChatWriter = new StreamWriter(m_ChatFile, Encoding.Unicode);
m_UdpClient = new UdpClient(new IPEndPoint(IPAddress.Any, LOCAL_PORT));
m_UdpClient.Client.ReceiveTimeout = SEND_RECV_TIMEOUT;
m_UdpClient.Client.SendTimeout = SEND_RECV_TIMEOUT;
m_UdpClient.BeginReceive(new AsyncCallback(ReceiveCallback), null);
}
public void StopWork()
{
m_UdpClient.Close();
m_ChatWriter.Flush();
m_ChatWriter.Close();
m_ChatFile.Close();
}
private void LogChat(IPAddress addr, string chatString)
{
string logString = string.Format("{0}\t{1}\t{2}\t{3}",
DateTime.Now.ToLongDateString(),
DateTime.Now.ToLongTimeString(),
addr,
chatString);
m_ChatWriter.WriteLine(logString);
}
private void SendCallback(IAsyncResult ar)
{
m_LastSendState.Complete = false;
m_UdpClient.EndSend(ar);
}
private void ReceiveCallback(IAsyncResult ar)
{
IPEndPoint remote = new IPEndPoint(IPAddress.Any, LOCAL_PORT);
byte[] revBytes = new byte[26]; //初始化接收区
try
{
revBytes = m_UdpClient.EndReceive(ar, ref remote);
}
catch(Exception ee) //网络异常
{
m_LastSendState.Complete = false;
FireAfterSendEvent();
Debug.WriteLine(ee.Message + ee.StackTrace);
}
int syncHeader = BitConverter.ToInt32(revBytes, 0); //同步
int revTick = BitConverter.ToInt32(revBytes, 4); //时间码
byte revVer = revBytes[8]; //消息版本号
byte revKind = revBytes[9]; //消息类型
ChatHost host = RegisterChatHost(remote.Address); //判断时间码
if (host.LastRevTick == revTick)
{
BeginReceive();
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -