解决方案 »
- C# 局部变量 WebBroswer 获取网页源代码
- WinXP, C#: 如何获取系统静音状态?
- c#关于combobox的问题 求解!!
- 请问一个模式窗体和无模式窗体的问题
- winform下的datagrid的datasource是IList时,如何设置样式?我没有办法了,100分求救!
- Button[] x, 如何。。。
- 不想做复合控件,想在文本框里加个按钮(请saucer(思归)、Eddie005(暴走005)以及各位老大帮助)
- listview如何对数字进行排序? 还有 如何在Column显示那个三角?
- 请问,DataGrid1.DataSource = SqlDataReader可以吗?
- C#转VB
- Cookies删除不掉?
- 求助——用什么控件做这样的界面啊?
还是先踏踏实实的巩固下socket的知识吧
using System.Text;
using System.IO;
using System.Net;
using ICSharpCode.SharpZipLib.GZip;
using System.Net.Sockets;
using System.Threading;
namespace ProcessCenter.SocketHelper
{ public class SocketHelper
{
#region 属性
/// <summary>
/// 网络发送超时时间
/// </summary>
public static string SendTimeout { set; get; } /// <summary>
/// 网络接收超时时间
/// </summary>
public static string ReceiveTimeout { set; get; }
#endregion #region 变量
private Encoding encoding = Encoding.GetEncoding("utf-8");
const int socketLength = 2000;
#endregion /// <summary>
/// 释放链接
/// </summary>
public void Close()
{
if (TcpClient.Instance != null)
{
TcpClient.Instance.Actived = false;
TcpClient.Instance.Client.Close();
TcpClient.Instance.Close();
}
} /// <summary>
/// 是否连接
/// </summary>
/// <returns></returns>
public bool isContect()
{
return TcpClient.Instance.Actived && TcpClient.Instance.Client.Connected;
} ///<summary>
///向服务器发送的请求
///</summary>
///<param name="URL">请求的地址</param>
///<param name="postData">向服务器发送的文本数据</param>
///<returns>服务器响应文本</returns>
public string OpenRead(string postData, int actionID)
{
byte[] sendBytes = encoding.GetBytes(postData);
SendData(sendBytes, actionID);
return GetData();
} /// <summary>
/// 向服务器发送的请求(数据压缩)
/// </summary>
/// <param name="URL"></param>
/// <param name="data"></param>
/// <returns></returns>
public string UploadCompress(string data, int actionID)
{
byte[] buffer = encoding.GetBytes(data);
MemoryStream stream = GZipStream(buffer, buffer.Length);
//发送请求数据
SendBinary(new byte[0], stream.ToArray(), actionID);
//返回响应文本
return GetData();
} /// <summary>
/// 上传文件到服务器
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="actionID">文件路径</param>
/// <returns>服务器响应文本</returns>
public string UploadFile(int actionID,string json, string filePath)
{
byte[] buffer;
//添加文件数据
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
buffer = new byte[fs.Length];
fs.Read(buffer, 0, int.Parse(fs.Length.ToString()));
} //发送二进制请求数据
SendBinary(encoding.GetBytes(json), buffer, actionID);
//返回响应文本
return GetData();
} /// <summary>
/// 下载文件
/// </summary>
/// <param name="json">请求json体</param>
/// <param name="actionID">请求类型</param>
/// <param name="result">请求结果</param>
/// <returns></returns>
public byte[] DownLoadFile(string json, int actionID, out string result)
{
SendData(encoding.GetBytes(json), actionID);
return GetBytes(out result);
}
/// <summary>
/// 初始化Socket连接
/// </summary>
/// <param name="server"></param>
public bool InitContection(string ip ,string port)
{
if (TcpClient.Instance.Actived)
{
Close();
}
try
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), int.Parse(port));
TcpClient.Instance.Init(endPoint, int.Parse(ReceiveTimeout), int.Parse(SendTimeout));
}
catch (Exception)
{
return false;
} return isContect(); } public void SetTimeOut(int multiple)
{
TcpClient.Instance.SetTimeout(multiple * int.Parse(ReceiveTimeout), multiple * int.Parse(SendTimeout));
}
}
}
/// <summary>
/// 获取服务器返回的字节数组
/// </summary>
/// <returns></returns>
private byte[] GetBytes(out string result)
{
byte[] buffer;
try
{
buffer = ReceiveBinary(out result);
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
return buffer;
} /// <summary>
/// GZIP压缩流方式
/// </summary>
/// <param name="stream">输入流</param>
/// <param name="BlockSize">压缩块大小</param>
/// <returns></returns>
private MemoryStream GZipStream(byte[] buffer, int BlockSize)
{
MemoryStream ms = new MemoryStream();
GZipOutputStream ZipStream = new GZipOutputStream(ms);
try
{
ZipStream.Write(buffer, 0, BlockSize);
}
finally
{
ZipStream.Finish();
}
return ms;
} /// <summary>
/// 向服务器发送二进制数据
/// </summary>
/// <param name="postStream"></param>
/// <param name="actionID"></param>
private void SendBinary(byte[] json, byte[] binary, int actionID)
{
try
{ if (TcpClient.Instance.Client != null && TcpClient.Instance.Client.Connected)
{
//操作类型(Action)
byte[] action = new byte[4];
action = BitConverter.GetBytes(actionID); //文本数据长度
byte[] jsonLength = new byte[4];
jsonLength = BitConverter.GetBytes(json.Length); //二进制数据长度
byte[] binaryLength = new byte[4];
binaryLength = BitConverter.GetBytes(binary.Length); TcpClient.Instance.Client.Send(CombineByte(action, jsonLength, binaryLength, json, binary));
}
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
} /// <summary>
/// 向服务器发送文本请求
/// </summary>
/// <param name="buffer">要发送的数据</param>
/// <param name="actionID">操作类型</param>
private void SendData(Byte[] json, int actionID)
{
try
{
if (TcpClient.Instance.Client != null && TcpClient.Instance.Client.Connected)
{
//操作类型(Action)
byte[] action = new byte[4];
action = BitConverter.GetBytes(actionID);
//协议文本长度
byte[] jsonLength = new byte[4];
jsonLength = BitConverter.GetBytes(json.Length);
//二进制数据长度
byte[] binaryLength = new byte[4];
binaryLength = BitConverter.GetBytes(0);
TcpClient.Instance.Client.Send(CombineByte(action, jsonLength, binaryLength, json));
}
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
/// <summary>
/// 获取服务器回发数据
/// </summary>
/// <returns></returns>
private string Receive()
{
string result = string.Empty; //接收操作类型4字节
byte[] actionID = new byte[4];
TcpClient.Instance.Client.Receive(actionID, 0, 4, System.Net.Sockets.SocketFlags.None);
int action = BitConverter.ToInt32(actionID, 0); //接收数据体长度4字节
byte[] jsonLength = new byte[4];
TcpClient.Instance.Client.Receive(jsonLength, 0, 4, System.Net.Sockets.SocketFlags.None);
int jsonlength = BitConverter.ToInt32(jsonLength, 0); //接收二进制长度4字节
byte[] binaryLength = new byte[4];
TcpClient.Instance.Client.Receive(binaryLength, 0, 4, System.Net.Sockets.SocketFlags.None);
//按长度接收数据体
if (jsonlength > 0)
{
using (MemoryStream ms = new MemoryStream())
{
//缓冲区大小
int bufferLength=0;
//实际读取字节数
int realReadCount = 0;
while (realReadCount < jsonlength)
{
if (realReadCount + socketLength < jsonlength)
bufferLength = socketLength;
else
bufferLength = jsonlength - realReadCount;
byte[] binary = new byte[bufferLength];
int count = TcpClient.Instance.Client.Receive(binary, 0, bufferLength, System.Net.Sockets.SocketFlags.None);
ms.Write(binary, 0, count);
realReadCount += count;
}
result = encoding.GetString(ms.ToArray(), 0,int.Parse(ms.Length.ToString()));
}
}
return result;
} /// <summary>
/// 获取文件
/// </summary>
/// <returns></returns>
private byte [] ReceiveBinary(out string result)
{
result = ""; //接收操作类型4字节
byte[] actionID = new byte[4];
TcpClient.Instance.Client.Receive(actionID, 0, 4, System.Net.Sockets.SocketFlags.None);
int action = BitConverter.ToInt32(actionID, 0); //接收数据体长度4字节
byte[] jsonLength = new byte[4];
TcpClient.Instance.Client.Receive(jsonLength, 0, 4, System.Net.Sockets.SocketFlags.None);
int jsonlength = BitConverter.ToInt32(jsonLength, 0);
//文件数据长度
byte[] binaryLength = new byte[4];
TcpClient.Instance.Client.Receive(binaryLength, 0, 4, System.Net.Sockets.SocketFlags.None);
int binarylength = BitConverter.ToInt32(binaryLength, 0); //按长度接收数据体
if (jsonlength > 0)
{
byte[] json = new byte[jsonlength];
TcpClient.Instance.Client.Receive(json, 0, jsonlength, System.Net.Sockets.SocketFlags.None);
result = encoding.GetString(json, 0, jsonlength);
} if (binarylength > 0)
{
using (MemoryStream ms = new MemoryStream())
{
//int index = 0;
//while (index+socketLength < binarylength)
//{
// byte[] binary = new byte[socketLength];
// int count = TcpClient.Instance.Client.Receive(binary, 0, socketLength,System.Net.Sockets.SocketFlags.None);
// ms.Write(binary, 0,count);
// index += count;
//}
//if (binarylength - index> 0)
//{
// byte[] binary = new byte[binarylength - index];
// int count=TcpClient.Instance.Client.Receive(binary, 0, binarylength - index, System.Net.Sockets.SocketFlags.None);
// ms.Write(binary, 0, count);
//} //缓冲区大小
int bufferLength = 0;
//实际读取字节数
int realReadCount = 0;
while (realReadCount < binarylength)
{
if (realReadCount + socketLength < binarylength)
bufferLength = socketLength;
else
bufferLength = binarylength - realReadCount;
byte[] binary = new byte[bufferLength];
int count = TcpClient.Instance.Client.Receive(binary, 0, bufferLength, System.Net.Sockets.SocketFlags.None);
ms.Write(binary, 0, count);
realReadCount += count;
}
return ms.ToArray();
}
}
return null;
} /// <summary>
/// 合并字节数组
/// </summary>
/// <returns></returns>
private byte[] CombineByte(byte[] a, byte[] b, byte[] c, byte[] d)
{
byte[] e = new byte[a.Length + b.Length + c.Length + d.Length];
a.CopyTo(e, 0);
b.CopyTo(e, a.Length);
c.CopyTo(e, a.Length + b.Length);
d.CopyTo(e, a.Length + b.Length + c.Length);
return e;
} /// <summary>
/// 合并字节数组
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <param name="d"></param>
/// <param name="e"></param>
/// <param name="f"></param>
/// <returns></returns>
private byte[] CombineByte(byte[] a, byte[] b, byte[] c, byte[] d, byte[] e)
{
byte[] f = new byte[a.Length + b.Length + c.Length + d.Length + e.Length];
a.CopyTo(f, 0);
b.CopyTo(f, a.Length);
c.CopyTo(f, a.Length + b.Length);
d.CopyTo(f, a.Length + b.Length + c.Length);
e.CopyTo(f, a.Length + b.Length + c.Length + d.Length);
return f;
} ///<summary>
///获取服务器响应文本
///</summary>
///<returns>服务器响应文本</returns>
private string GetData()
{
string result = string.Empty;
try
{
result = Receive();
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
return result;
}
#endregion
再次连接时,提示无法访问已释放的对象。
你在创建一次对象就好了嘛。
tcpclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
你在创建一次对象就好了嘛。
tcpclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
就是不想再创建了,直接在类的构造函数里创建一个不行吗?只关闭连接不释放对象
你在创建一次对象就好了嘛。
tcpclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
就是不想再创建了,直接在类的构造函数里创建一个不行吗?只关闭连接不释放对象Socket关了就不能重用了。
你看看TcpClient就是这么干的吧。
你在创建一次对象就好了嘛。
tcpclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
就是不想再创建了,直接在类的构造函数里创建一个不行吗?只关闭连接不释放对象Socket关了就不能重用了。
你看看TcpClient就是这么干的吧。
谢谢马桶哥,看来只能这样了