#define
DUBEG
using System;
using System.IO;
using System.Text;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
namespace SocketServer
... {
/**//// <summary>
/// 传输对象类,接收缓冲区为默认值 8192 个字节。
/// </summary>
public class TcpTranslate
...{
private AutoResetEvent fileResponsion; //接收文件应答.
网络事件#region 网络事件
/**//// <summary>
/// 连接成功事件
/// </summary>
public event NetEvent Connect;
/**//// <summary>
/// 断开连接事件
/// </summary>
public event NetEvent DisConnect;
/**//// <summary>
/// 接收到数据事件
/// </summary>
public event NetEvent Receive;
/**//// <summary>
/// 接收到文本事件
/// </summary>
public event NetEvent ReceiveText;
/**//// <summary>
/// 接收完文件事件
/// </summary>
public event NetEvent ReceiveFile;
/**//// <summary>
/// 接收完对象事件
/// </summary>
public event NetEvent ReceiveObje;
/**//// <summary>
/// 发送完文件事件
/// </summary>
public event NetEvent SendOverFile;
#endregion
字段#region 字段
private Socket _socket; // 客户连接类
private Stream _bufferObject; // 缓存所有接收到的对象数据
private FileRece _bufferFile; // 缓存所有接收到的文件数据
private FileSend _sendFile; // 要发送文件
private int _recObjeLen = -1; // 接收到的对象的长度
private int _recFileLen = -1; // 接收到的文件的长度
string _filePath; //文件的保存位置
string _fileName;
private IPEndPoint _iep;
private List<byte> _bufferBags; //缓存包
private bool _allowSendText = true;
private bool _allowSendObje = true;
private bool _allowSendFile = true;
private bool _isConnected;
public const int _bagSize = 8192; //缓存大小
const int _headLen = 4; //包头大小,用于保存要发送数据的总长度
const int _headLens = 5; //第一包包头大小
//包头第一个字节,表示此包所包含的内容
readonly byte[] _textHead = new byte[] ...{ 0 };//文本
readonly byte[] _objeHead = new byte[] ...{ 1 };//对象
readonly byte[] _fileHead = new byte[] ...{ 2 };//文件
int receiveLen; //接收到的未处理的数据的长度
//int sendBigs; //发送的包数
#endregion
属性#region 属性
/**//// <summary>
/// 获取远程终结点
/// </summary>
public EndPoint RemoteEndPoint
...{
get
...{
return this._socket.RemoteEndPoint;
}
}
/**//// <summary>
/// Socket是否已连接
/// </summary>
public bool Connected
...{
get
...{
return this._socket.Connected;
}
}
/**//// <summary>
/// 设置或获取临时文件夹的路径
/// </summary>
public string FilePath
...{
get ...{ return _filePath; }
set ...{ _filePath = value; }
}
#endregion
构造函数#region 构造函数
TcpTranslate()
...{
_filePath = Environment.CurrentDirectory + @"Temp";
_bufferBags = new List<byte>(_bagSize);
if (!Directory.Exists(_filePath))
...{
Directory.CreateDirectory(_filePath);
}
}
/**//// <summary>
/// 服务器端调用此构造函数
/// </summary>
/// <param name="_socket">Socket成功连接的Socket</param>
public TcpTranslate(Socket socket)
: this()
...{
_socket = socket;
_socket.ReceiveBufferSize = _bagSize;
_isConnected = true;
}
/**//// <summary>
/// 客户端调用此构造函数
/// </summary>
/// <param name="ip">要连接的服务器IP</param>
/// <param name="port">要连接的端口</param>
public TcpTranslate(string ip, int port)
: this()
...{
_iep = new IPEndPoint(IPAddress.Parse(ip), port);
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.ReceiveBufferSize = _bagSize;
_isConnected = false;
}
#endregion
[System.Diagnostics.Conditional("DUBEG")]
public static void WriteLine(string message)
...{
Console.WriteLine(message);
}
/**//// <summary>
/// 开始接收数据
/// </summary>
public void StartReceive()
...{
if (_isConnected)
...{
byte[] bytes = new byte[_bagSize];
_socket.BeginReceive(bytes, 0, _bagSize, SocketFlags.None,
new AsyncCallback(ReceivceData), bytes);
}
else
...{
_socket.BeginConnect(_iep, new AsyncCallback(connected), _socket);
}
}
private void connected(IAsyncResult iar)
...{
_isConnected = true;
StartReceive();
if (Connect != null) Connect(this, this);
}
/**//// <summary>
/// 接收数据回调函数
/// </summary>
/// <param name="ar"></param>
private void ReceivceData(IAsyncResult ar)
...{
try
...{
SocketError sErr;
//接收到的数据长度.
int receLen = _socket.EndReceive(ar, out sErr);
byte[] receBytes = ar.AsyncState as byte[];
if (receLen != _bagSize)
...{
byte[] currentBin = new byte[receLen];
Array.Copy(receBytes,0,currentBin,0,receLen);
_bufferBags.AddRange(currentBin);
if (_bufferBags.Count == _bagSize)
...{
receBytes = _bufferBags.ToArray();
receLen = _bagSize;
_bufferBags.Clear();
}
else
...{
//byte[] bin = new byte[_bagSize];
//_socket.BeginReceive(bin, 0, bin.Length, SocketFlags.None,
// new AsyncCallback(ReceivceData), bin);
return;
}
}
switch (receBytes[0])
...{
case 1: //接收到文本
ReceivceText(receLen, receBytes);
break;
case 2: //接收到对象
//ReceivceObje(receLen, receBytes);
break;
case FileSend.BagMark: //接收到文件
ReceivceFile(receLen, receBytes);
break;
//case 254: //响应包
// fileResponsion.Set();
// break;
//case 255: //重发请求.重新发送包
// repeatSend();
// break;
default: //接收错误,请求重发
requestRepeatSend();
WriteLine("错误的数据包:包头为 " + receBytes[0].ToString() + " Socket错误代码:" + sErr.ToString());
WriteLine("要正请求重新发送第" + _bufferFile.CurrentBag + "包");
break;
}
//继续接收数据
byte[] bytes = new byte[_bagSize];
_socket.BeginReceive(bytes, 0, bytes.Length, SocketFlags.None,
new AsyncCallback(ReceivceData), bytes);
return;
}
catch (SocketException socketErr)
...{
WriteLine(socketErr.Message);
}
catch (ObjectDisposedException socketClose)
...{
WriteLine(socketClose.Message);
}
catch (Exception err)
...{
WriteLine(err.Message);
}
//断开连接事件
if (DisConnect != null) DisConnect(_socket, this);
_recObjeLen = -1;
_recFileLen = -1;
}
void ReceivceFile(int receLen, byte[] receBytes)
...{
int bagSequence = FileRece.ReadBagSequence(receBytes);
if (bagSequence == 0 ) //读第一包.初始化接收文件类
...{
if (_recFileLen == -1)
...{
_bufferFile = new FileRece();
_bufferFile.ReceivedFile += new FileEvent(reFileEnd);
_bufferFile.Initialize(receBytes);
_recFileLen += receLen;
}
else
...{
WriteLine("接收到错误的包");
}
}
else if (bagSequence == _bufferFile.NextBag)
...{
_bufferFile.Write(receBytes);
_recFileLen += receLen;
}
SendState(receBytes);
}
void reFileEnd(FileBase f)
...{
_recFileLen = -1;
//接收完数据事件
WriteLine("文件接收完成");
if (ReceiveFile != null) ...{ ReceiveFile(_fileName, this); }
}
void repeatSend()
...{
byte[] reSendBin = _sendFile.GetBags(_sendFile.CurrentBag - 1);
_socket.BeginSend(reSendBin, 0, reSendBin.Length, SocketFlags.None, new AsyncCallback(SendEnd), reSendBin);
}
void requestRepeatSend()
...{
byte[] stat = new byte[_bagSize];
stat[0] = 255;
_socket.BeginSend(stat, 0, stat.Length, SocketFlags.None, new AsyncCallback(SendEnd), stat);
}
/**//// <summary>
/// 接收多包时的应答包
/// </summary>
/// <param name="content">状态</param>
protected virtual void SendState(byte[] receBytes)
...{
byte[] stat = new byte[_bagSize];
stat[0] = 254;
Array.Copy(receBytes, 1, stat, 1, 7);
_socket.BeginSend(stat, 0, stat.Length, SocketFlags.None, new AsyncCallback(SendEnd), stat);
}
protected virtual void SendEnd(IAsyncResult iar)
...{
_socket.EndSend(iar);
}
void ReceivceText(int receLen, byte[] receBytes)
...{
string reStr = Encoding.Default.GetString(receBytes, 1, receLen - 1).TrimEnd('空');
//接收完数据事件
if (ReceiveText != null) ...{ ReceiveText(reStr, this); }
WriteLine(reStr);
}
/**//// <summary>
/// 发送文本
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public bool SendText(string text)
...{
if (_allowSendText)
...{
_allowSendText = false; //禁止发送文本
Stream _stream = new MemoryStream(Encoding.Default.GetBytes(text)); //得到文本的内存流
return true;
}
return false;
}
/**//// <summary>
/// 发送文件
/// </summary>
/// <param name="_filePath">文件路径</param>
/// <returns></returns>
public bool SendFile(string filePath)
...{
if (_allowSendFile && File.Exists(filePath))
...{
_allowSendFile = false; //禁止发送文件
_sendFile = new FileSend(_bagSize, filePath);
byte[] sendBin = _sendFile.ReadBase();
if (sendBin.Length > 0)
...{
fileResponsion = new AutoResetEvent(false);
_socket.BeginSend(sendBin, 0, sendBin.Length, SocketFlags.None, //开始异步发送
new AsyncCallback(sendFileCallBack), _sendFile);
}
else
...{
_socket.Send(new byte[] ...{ });
_allowSendFile = true;
}
return true;
}
return false;
}
private void sendFileCallBack(IAsyncResult ar)
...{
_socket.EndSend(ar);
//FileSend sendfiles = (FileSend)ar.AsyncState;
byte[] sendBin = _sendFile.Read();
//fileResponsion.WaitOne(); //等待接收方作回应答
if (sendBin.Length > 0)
...{
_socket.BeginSend(sendBin, 0, _bagSize, SocketFlags.None, //开始异步发送
new AsyncCallback(sendFileCallBack), _sendFile);
}
else
...{
_socket.Send(new byte[] ...{ });
if (SendOverFile != null)
...{
SendOverFile("文件发送完成", this);
}
_allowSendFile = true;
}
}
}
}
using System;
using System.IO;
using System.Text;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
namespace SocketServer
... {
/**//// <summary>
/// 传输对象类,接收缓冲区为默认值 8192 个字节。
/// </summary>
public class TcpTranslate
...{
private AutoResetEvent fileResponsion; //接收文件应答.
网络事件#region 网络事件
/**//// <summary>
/// 连接成功事件
/// </summary>
public event NetEvent Connect;
/**//// <summary>
/// 断开连接事件
/// </summary>
public event NetEvent DisConnect;
/**//// <summary>
/// 接收到数据事件
/// </summary>
public event NetEvent Receive;
/**//// <summary>
/// 接收到文本事件
/// </summary>
public event NetEvent ReceiveText;
/**//// <summary>
/// 接收完文件事件
/// </summary>
public event NetEvent ReceiveFile;
/**//// <summary>
/// 接收完对象事件
/// </summary>
public event NetEvent ReceiveObje;
/**//// <summary>
/// 发送完文件事件
/// </summary>
public event NetEvent SendOverFile;
#endregion
字段#region 字段
private Socket _socket; // 客户连接类
private Stream _bufferObject; // 缓存所有接收到的对象数据
private FileRece _bufferFile; // 缓存所有接收到的文件数据
private FileSend _sendFile; // 要发送文件
private int _recObjeLen = -1; // 接收到的对象的长度
private int _recFileLen = -1; // 接收到的文件的长度
string _filePath; //文件的保存位置
string _fileName;
private IPEndPoint _iep;
private List<byte> _bufferBags; //缓存包
private bool _allowSendText = true;
private bool _allowSendObje = true;
private bool _allowSendFile = true;
private bool _isConnected;
public const int _bagSize = 8192; //缓存大小
const int _headLen = 4; //包头大小,用于保存要发送数据的总长度
const int _headLens = 5; //第一包包头大小
//包头第一个字节,表示此包所包含的内容
readonly byte[] _textHead = new byte[] ...{ 0 };//文本
readonly byte[] _objeHead = new byte[] ...{ 1 };//对象
readonly byte[] _fileHead = new byte[] ...{ 2 };//文件
int receiveLen; //接收到的未处理的数据的长度
//int sendBigs; //发送的包数
#endregion
属性#region 属性
/**//// <summary>
/// 获取远程终结点
/// </summary>
public EndPoint RemoteEndPoint
...{
get
...{
return this._socket.RemoteEndPoint;
}
}
/**//// <summary>
/// Socket是否已连接
/// </summary>
public bool Connected
...{
get
...{
return this._socket.Connected;
}
}
/**//// <summary>
/// 设置或获取临时文件夹的路径
/// </summary>
public string FilePath
...{
get ...{ return _filePath; }
set ...{ _filePath = value; }
}
#endregion
构造函数#region 构造函数
TcpTranslate()
...{
_filePath = Environment.CurrentDirectory + @"Temp";
_bufferBags = new List<byte>(_bagSize);
if (!Directory.Exists(_filePath))
...{
Directory.CreateDirectory(_filePath);
}
}
/**//// <summary>
/// 服务器端调用此构造函数
/// </summary>
/// <param name="_socket">Socket成功连接的Socket</param>
public TcpTranslate(Socket socket)
: this()
...{
_socket = socket;
_socket.ReceiveBufferSize = _bagSize;
_isConnected = true;
}
/**//// <summary>
/// 客户端调用此构造函数
/// </summary>
/// <param name="ip">要连接的服务器IP</param>
/// <param name="port">要连接的端口</param>
public TcpTranslate(string ip, int port)
: this()
...{
_iep = new IPEndPoint(IPAddress.Parse(ip), port);
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.ReceiveBufferSize = _bagSize;
_isConnected = false;
}
#endregion
[System.Diagnostics.Conditional("DUBEG")]
public static void WriteLine(string message)
...{
Console.WriteLine(message);
}
/**//// <summary>
/// 开始接收数据
/// </summary>
public void StartReceive()
...{
if (_isConnected)
...{
byte[] bytes = new byte[_bagSize];
_socket.BeginReceive(bytes, 0, _bagSize, SocketFlags.None,
new AsyncCallback(ReceivceData), bytes);
}
else
...{
_socket.BeginConnect(_iep, new AsyncCallback(connected), _socket);
}
}
private void connected(IAsyncResult iar)
...{
_isConnected = true;
StartReceive();
if (Connect != null) Connect(this, this);
}
/**//// <summary>
/// 接收数据回调函数
/// </summary>
/// <param name="ar"></param>
private void ReceivceData(IAsyncResult ar)
...{
try
...{
SocketError sErr;
//接收到的数据长度.
int receLen = _socket.EndReceive(ar, out sErr);
byte[] receBytes = ar.AsyncState as byte[];
if (receLen != _bagSize)
...{
byte[] currentBin = new byte[receLen];
Array.Copy(receBytes,0,currentBin,0,receLen);
_bufferBags.AddRange(currentBin);
if (_bufferBags.Count == _bagSize)
...{
receBytes = _bufferBags.ToArray();
receLen = _bagSize;
_bufferBags.Clear();
}
else
...{
//byte[] bin = new byte[_bagSize];
//_socket.BeginReceive(bin, 0, bin.Length, SocketFlags.None,
// new AsyncCallback(ReceivceData), bin);
return;
}
}
switch (receBytes[0])
...{
case 1: //接收到文本
ReceivceText(receLen, receBytes);
break;
case 2: //接收到对象
//ReceivceObje(receLen, receBytes);
break;
case FileSend.BagMark: //接收到文件
ReceivceFile(receLen, receBytes);
break;
//case 254: //响应包
// fileResponsion.Set();
// break;
//case 255: //重发请求.重新发送包
// repeatSend();
// break;
default: //接收错误,请求重发
requestRepeatSend();
WriteLine("错误的数据包:包头为 " + receBytes[0].ToString() + " Socket错误代码:" + sErr.ToString());
WriteLine("要正请求重新发送第" + _bufferFile.CurrentBag + "包");
break;
}
//继续接收数据
byte[] bytes = new byte[_bagSize];
_socket.BeginReceive(bytes, 0, bytes.Length, SocketFlags.None,
new AsyncCallback(ReceivceData), bytes);
return;
}
catch (SocketException socketErr)
...{
WriteLine(socketErr.Message);
}
catch (ObjectDisposedException socketClose)
...{
WriteLine(socketClose.Message);
}
catch (Exception err)
...{
WriteLine(err.Message);
}
//断开连接事件
if (DisConnect != null) DisConnect(_socket, this);
_recObjeLen = -1;
_recFileLen = -1;
}
void ReceivceFile(int receLen, byte[] receBytes)
...{
int bagSequence = FileRece.ReadBagSequence(receBytes);
if (bagSequence == 0 ) //读第一包.初始化接收文件类
...{
if (_recFileLen == -1)
...{
_bufferFile = new FileRece();
_bufferFile.ReceivedFile += new FileEvent(reFileEnd);
_bufferFile.Initialize(receBytes);
_recFileLen += receLen;
}
else
...{
WriteLine("接收到错误的包");
}
}
else if (bagSequence == _bufferFile.NextBag)
...{
_bufferFile.Write(receBytes);
_recFileLen += receLen;
}
SendState(receBytes);
}
void reFileEnd(FileBase f)
...{
_recFileLen = -1;
//接收完数据事件
WriteLine("文件接收完成");
if (ReceiveFile != null) ...{ ReceiveFile(_fileName, this); }
}
void repeatSend()
...{
byte[] reSendBin = _sendFile.GetBags(_sendFile.CurrentBag - 1);
_socket.BeginSend(reSendBin, 0, reSendBin.Length, SocketFlags.None, new AsyncCallback(SendEnd), reSendBin);
}
void requestRepeatSend()
...{
byte[] stat = new byte[_bagSize];
stat[0] = 255;
_socket.BeginSend(stat, 0, stat.Length, SocketFlags.None, new AsyncCallback(SendEnd), stat);
}
/**//// <summary>
/// 接收多包时的应答包
/// </summary>
/// <param name="content">状态</param>
protected virtual void SendState(byte[] receBytes)
...{
byte[] stat = new byte[_bagSize];
stat[0] = 254;
Array.Copy(receBytes, 1, stat, 1, 7);
_socket.BeginSend(stat, 0, stat.Length, SocketFlags.None, new AsyncCallback(SendEnd), stat);
}
protected virtual void SendEnd(IAsyncResult iar)
...{
_socket.EndSend(iar);
}
void ReceivceText(int receLen, byte[] receBytes)
...{
string reStr = Encoding.Default.GetString(receBytes, 1, receLen - 1).TrimEnd('空');
//接收完数据事件
if (ReceiveText != null) ...{ ReceiveText(reStr, this); }
WriteLine(reStr);
}
/**//// <summary>
/// 发送文本
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public bool SendText(string text)
...{
if (_allowSendText)
...{
_allowSendText = false; //禁止发送文本
Stream _stream = new MemoryStream(Encoding.Default.GetBytes(text)); //得到文本的内存流
return true;
}
return false;
}
/**//// <summary>
/// 发送文件
/// </summary>
/// <param name="_filePath">文件路径</param>
/// <returns></returns>
public bool SendFile(string filePath)
...{
if (_allowSendFile && File.Exists(filePath))
...{
_allowSendFile = false; //禁止发送文件
_sendFile = new FileSend(_bagSize, filePath);
byte[] sendBin = _sendFile.ReadBase();
if (sendBin.Length > 0)
...{
fileResponsion = new AutoResetEvent(false);
_socket.BeginSend(sendBin, 0, sendBin.Length, SocketFlags.None, //开始异步发送
new AsyncCallback(sendFileCallBack), _sendFile);
}
else
...{
_socket.Send(new byte[] ...{ });
_allowSendFile = true;
}
return true;
}
return false;
}
private void sendFileCallBack(IAsyncResult ar)
...{
_socket.EndSend(ar);
//FileSend sendfiles = (FileSend)ar.AsyncState;
byte[] sendBin = _sendFile.Read();
//fileResponsion.WaitOne(); //等待接收方作回应答
if (sendBin.Length > 0)
...{
_socket.BeginSend(sendBin, 0, _bagSize, SocketFlags.None, //开始异步发送
new AsyncCallback(sendFileCallBack), _sendFile);
}
else
...{
_socket.Send(new byte[] ...{ });
if (SendOverFile != null)
...{
SendOverFile("文件发送完成", this);
}
_allowSendFile = true;
}
}
}
}