62,025
社区成员
发帖
与我相关
我的任务
分享
IPEndPoint ipe = new IPEndPoint(SvrIp, SvrPort);
//在服务器端创建一个负责监IP地址跟端口号的Socket
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//监听
_socket.Bind(ipe);
_socket.Listen(50);
//设置异步方法接受客户端连接
_socket.BeginAccept(new AsyncCallback(Listen), _socket);
void Listen(IAsyncResult ar)
{
try
{
//获取用户定义的对象,它限定或包含关于异步操作的信息。
Socket listener = (Socket)ar.AsyncState;
//异步接受传入的连接尝试,并创建新的 Socket 来处理远程主机通信。
Socket client = listener.EndAccept(ar);
SocketClient state;
//SId默认为值为100,Uid默认值为10001
if (Sid > 0 && Sid < 10000)
state = new SocketClient(Sid, client);
else
{
//我断点在这里
Uid = Uid + 1;
state = new SocketClient(Uid, client);
}
if (Sid > 0 && Sid < 10000)//说明是服务端,记录登录状态
{
Sid = -1;//服务端Id只允许使用1次
}
//继续接受客户端
_socket.BeginAccept(new AsyncCallback(Listen), _socket);
}
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;
using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Net;
namespace Msg
{
/// <summary>
/// 处理每一个连接的客户
/// </summary>
public class SocketClient
{
#region === 私有变量 ===
/// <summary>
/// 客户端SOCKET
/// </summary>
private Socket _workSocket = null;
private int _uid;
private string _userName;
private const int DefaultBufferSize = 1024 * 2;
private byte[] buffer;
public event EventHandler<ChatEventArgs> ChatEvent;
#endregion
#region === 公开属性 ===
/// <summary>
/// 客户端ID
/// </summary>
public int Uid
{
get { return _uid; }
set { _uid = value; }
}
public string UserName
{
get { return _userName; }
set { _userName = value; }
}
#endregion
#region === 构造函数 ===
/// <summary>
/// 构造函数
/// </summary>
public SocketClient(int id, Socket socket)
{
this._workSocket = socket;
this.Uid = id;
this.UserName = Common.IpAds(Common.GetIP());
buffer = new byte[DefaultBufferSize];
}
#endregion
#region === 开启独自数据处理 ===
/// <summary>
/// 开启独自数据处理
/// </summary>
public void Start()
{
try
{
byte[] inValue = new byte[] { 1, 0, 0, 0, 0x20, 0x4e, 0, 0, 0xd0, 0x07, 0, 0 }; //首次探测时间20 秒, 间隔侦测时间2 秒
//byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探测时间5 秒, 间隔侦测时间2 秒
_workSocket.IOControl(IOControlCode.KeepAliveValues, inValue, null);
}
catch { return; }
//开始接受来自该客户端的数据
_workSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,
new AsyncCallback(ReceiveMessage), this);
}
/// <summary>
/// 断开与客户端的连接
/// </summary>
public void Shutdown()
{
try
{
_workSocket.Shutdown(SocketShutdown.Both);
_workSocket.Close();
}
catch { }
}
#endregion
#region === 接受客户端建立连接后的处理线程 ===
void ReceiveMessage(IAsyncResult ar)
{
try
{
SocketClient state = (SocketClient)ar.AsyncState;
Socket client = state._workSocket;
//登录成功,则进入消息等待中
int BytesRead = 0;
if (client.Connected)
{
try
{ BytesRead = client.EndReceive(ar); }
catch
{
Console.WriteLine("发生异常错误");
return;
}
if (BytesRead == 0)
{
Console.WriteLine("没有消息需要处理");
return;
}
//格式化帧头
DataDecrypt dd = new DataDecrypt(buffer);
string msg = dd.AnalyticData(buffer, dd.Length);
//处理消息
}
//继续接收来自来客户端的数据
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), state);
}
catch { }
}
#endregion
#region === 把消息发送到对应的客户端 ===
public void Send(ChatEventArgs o)
{
try
{
byte[] bt = DataDecrypt.PackData("{" + o.ToString() + "}");
_workSocket.Send(bt);
Thread.Sleep(20);
}
catch { }
}
/// <summary>
/// 往关联的客户端发送数据
/// </summary>
public void Response(string message)
{
_workSocket.Send(Encoding.UTF8.GetBytes(message));
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Collections;
using System.Web.Script.Serialization;
using System.Web;
using System.IO;
using System.Xml;
using Msg.Main;
using System.Media;
namespace Msg
{
public class SocketListen
{
private IPAddress _ip;//绑定的IP地址
private int _port; //使用的端口
public static Hashtable _clientList = null;//客户端列表
private Socket _socket = null;//用于侦听的Socket套接字
private byte[] buffer = new byte[1024 * 2];
private bool _run = false; //运行中
private static int _uid = 10000;//新分配给客户端的Id > 10000
private static int _sid = 0;//主要记录服务器自定义的id < 10000
private ManualResetEvent LoginValidataDone = new ManualResetEvent(true);
private ManualResetEvent sendDone = new ManualResetEvent(true);
/// <summary>
/// 客服Id
/// </summary>
public static int Sid
{
get { return _sid; }
set { _sid = value; }
}
/// <summary>
/// 客户端Id
/// </summary>
public static int Uid
{
get { return _uid; }
set { _uid = value; }
}
#region === 开始监听 ===
/// <summary>
/// 开始侦听
/// </summary>
public bool Start()
{
try
{
//创建端口号对象
IPEndPoint ipe = new IPEndPoint(SvrIp, SvrPort);
//在服务器端创建一个负责监IP地址跟端口号的Socket
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//监听
_socket.Bind(ipe);
_socket.Listen(50);
//设置异步方法接受客户端连接
_socket.BeginAccept(new AsyncCallback(Listen), _socket);
_run = true;
return true;
}
catch (Exception)
{
_run = false;
return false;
}
}
#endregion
#region === 等待客户端的连接 ===
/// <summary>
/// 等待客户端的连接
/// </summary>
/// <param name="ar"></param>
void Listen(IAsyncResult ar)
{
try
{
//如果服务器停止了服务,就不能再接收新的客户端
if (!_run)
return;
//获取用户定义的对象,它限定或包含关于异步操作的信息。
Socket listener = (Socket)ar.AsyncState;
//异步接受传入的连接尝试,并创建新的 Socket 来处理远程主机通信。
Socket client = listener.EndAccept(ar);
//服务端可以自定义ID
SocketClient state;
if (Sid >= 0 && Sid < 10000)
state = new SocketClient(Sid, client);
else
{
Uid = Uid + 1;
state = new SocketClient(Uid, client);
}
state.ChatEvent += new EventHandler<ChatEventArgs>(State_ChatEvent);
//登录认证,只有等ReceiveLoginValidateCallback执行完后才会继续
LoginValidataDone.Reset();
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveLoginValidateCallback), ar);
LoginValidataDone.WaitOne();
Agreement agr = new Agreement(Encoding.UTF8.GetString(buffer, 0, buffer.Length));
if (agr.GetValue("swfobject") == "true")//(agr.Response。ToString().IndexOf("<policy-file-request/>") >= 0)
{
string xml = "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\0";
state.Response(xml);//向客户端发送策略文件
}
else
state.Response(agr.Response); //服务器作出握手回应
//开启独自异步接收消息数据
state.Start();
//将客户端信息置于列表中
if (_clientList.ContainsKey(state.Uid))
_clientList.Remove(state.Uid);
_clientList.Add(state.Uid, state);
if (Sid > 0 && Sid < 10000)//说明是服务端,记录登录状态
{
Common.Record(Sid, true);
Sid = -1;//服务端Id只允许使用1次
}
//继续接受客户端
_socket.BeginAccept(new AsyncCallback(Listen), _socket);
}
catch (Exception)
{
//设置异步方法接受客户端连接
_socket.BeginAccept(new AsyncCallback(Listen), _socket);
}
}
#endregion
#region === 接收处理相关消息 ====
/// <summary>
/// 接收处理相关消息
/// </summary>
/// <param name="sender">socket对象</param>
/// <param name="e">消息参数</param>
void State_ChatEvent(object sender, ChatEventArgs e)
{
SocketClient sc = (SocketClient)sender;
sc.Send(e);
}
private void ReceiveLoginValidateCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndReceive(ar);
LoginValidataDone.Set();
}
catch
{
LoginValidataDone.Set();
}
}
#endregion