新手研究Socket,报错为:
StartInternal(0,0):引发类型为“System.OutOfMemoryException”的异常。
恳请帮忙找下错误,该怎么改阿??
using SilverlightTest.ClassHandle;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightTest
{
public partial class MainPage : UserControl
{
/// <summary>
/// 初始信号量
/// </summary>
AutoResetEvent waitevent = new AutoResetEvent (false );
/// <summary>
/// 读取文件的当前位置
/// </summary>
long position = 0;
/// <summary>
/// 记录读取文件总长度
/// </summary>
long readcount = 0;
/// <summary>
///
/// </summary>
string splitChar = "^" ;
/// <summary>
/// 开始和结束标志
/// </summary>
byte[] endstr = Encoding.UTF8.GetBytes( "^" );
/// <summary>
/// 文件传输状态
/// 默认为数据包头等待上传
/// </summary>
HandFileState .HandDataState handstate = HandFileState .HandDataState .HeadPathLoading;
/// <summary>
/// 选择的文件信息
/// </summary>
FileInfo fileinfo;
/// <summary>
/// 获取要连接的ip
/// </summary>
string host = App.GetParam( "ip" );
/// <summary>
/// 获取要连接的端口
/// </summary>
int port = Convert.ToInt32( App.GetParam( "host" ));
/// <summary>
/// 获取文件扩展名(可以上传到的文件格式)
/// </summary>
string extens = App.GetParam( "extens" );
/// <summary>
///
/// </summary>
public MainPage()
{
InitializeComponent();
}
/// <summary>
/// 获取自定义文件扩展名参数,并重组字符串。
/// </summary>
/// <param name="sysmbol"></param>
/// <param name="_extens"></param>
/// <returns></returns>
string GetExtens(
string sysmbol,
string[] _extens)
{
StringBuilder extenstr = new StringBuilder ();
foreach ( string a in _extens)
{
extenstr.Append( "*." + a + sysmbol);
}
string _extenstr = extenstr.ToString();
string newextenstr = _extenstr.Substring(0, _extenstr.LastIndexOf(sysmbol));
return newextenstr;
}
/// <summary>
/// 浏览选择文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click_1( object sender, RoutedEventArgs e)
{
string[] _extens = extens.Split( '.');
OpenFileDialog dialog = new OpenFileDialog ();
dialog.Multiselect = false;
dialog.Filter = "视频(" + GetExtens("," , _extens) + ")|" + GetExtens(";" , _extens);
if (dialog.ShowDialog().Value)
{
fileinfo = dialog.File;
if (!fileinfo.Exists)
{
MessageBox .Show("选择的文件不存在!" );
return;
}
if (! OperFile.IsverFile(
fileinfo,
_extens))
{
MessageBox .Show("当前只能上传" + GetExtens( ",", _extens) + "格式的文件!" );
return;
}
filename.Content = fileinfo.Name + "(" + fileinfo.Length / 1024 / 1024 + "M)" ;
progress.Minimum = 0;
progress.Maximum = fileinfo.Length;
}
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click_3( object sender, RoutedEventArgs e)
{
if (fileinfo == null)
{
MessageBox .Show("请选择上传文件!" );
return;
}
Socket socket = new Socket( AddressFamily .InterNetwork, SocketType .Stream, ProtocolType .Tcp);
//连接Socket并发送文件路径数据包
Connect(socket, GetHeadByFilePath());
}
/// <summary>
/// 取消上传
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click_2( object sender, RoutedEventArgs e)
{
filename.Content = "" ;
progress.Value = 0;
fileinfo = null;
}
/// <summary>
/// 连接Socket
/// </summary>
/// <param name="usertoken"></param>
void Connect( Socket socket, byte[] usertoken)
{
SocketAsyncEventArgs args = new SocketAsyncEventArgs ();
args.RemoteEndPoint = new DnsEndPoint (host, port);
args.UserToken = usertoken;
args.Completed += new EventHandler <SocketAsyncEventArgs >(ConnectComplete);
socket.ConnectAsync(args);
}
/// <summary>
/// 连接成功的回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ConnectComplete( object sender, SocketAsyncEventArgs e)
{
Socket socket = sender as Socket;
byte[] bytes = ( byte[])e.UserToken;
Socket_ConnectAndSend(socket, bytes, e);
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="socket"></param>
/// <param name="bytes"></param>
/// <param name="e"></param>
void Socket_ConnectAndSend( Socket socket, byte[] bytes, SocketAsyncEventArgs e)
{
if (e.SocketError != SocketError .Success)
{
return;
}
SocketAsyncEventArgs args = new SocketAsyncEventArgs ();
args.RemoteEndPoint = e.RemoteEndPoint;
args.SetBuffer(bytes, 0, bytes.Length);
args.Completed += new EventHandler <SocketAsyncEventArgs >(SendComplete);
socket.SendAsync(args);
}
/// <summary>
/// 发送成功的回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void SendComplete( object sender, SocketAsyncEventArgs e)
{
Socket socket = sender as Socket;
byte[] bytes = new byte[1024];
if (e.SocketError != SocketError .Success)
{
return;
}
SocketAsyncEventArgs args = new SocketAsyncEventArgs ();
args.RemoteEndPoint = e.RemoteEndPoint;
args.SetBuffer(bytes, 0, bytes.Length);
args.Completed += new EventHandler <SocketAsyncEventArgs >(ReceiveComplate);
socket.ReceiveAsync(args);
}
/// <summary>
/// 接收成功的回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ReceiveComplate( object sender, SocketAsyncEventArgs e)
{
Socket socket = sender as Socket;
char _splitChar = splitChar.ToCharArray()[0];
List< byte> listreceive = new List< byte>(1024);
if (e.Buffer[e.Offset] == endstr[0] && e.BytesTransferred > 0)
{
for ( int i = e.Offset + 1; i < e.BytesTransferred; i++)
{
listreceive.Add(e.Buffer[i]);
if (e.Buffer[i] == _splitChar && listreceive.Count == 1)
{
break;
}
}
}
//判定数据发送接收状态
handstate = GetStates(listreceive);
if (handstate == HandFileState .HandDataState .Error)
{
MessageBox .Show("文件数据传输错误!" );
}
//如果文件路径包头发送成功,则发送文件长度包头数据
if (handstate == HandFileState .HandDataState .HeadPathFinish)
{
Socket_ConnectAndSend(socket, GetHeadByDataLen(), e);
}
if (handstate == HandFileState .HandDataState .DatalenFinish)
{
waitevent.Set();
Thread.Sleep(5);
}
if (handstate == HandFileState .HandDataState .DataFinish)
{
waitevent.Set();
Thread.Sleep(5);
this.Dispatcher.BeginInvoke(() => { this.progress.Value = position; });
}
//如果文件长度包头数据发送成功或者真实数据传输成功,则读取文件信息并发送数据
while ( true)
{
try
{
Thread rs = null;
if (rs != null)
{
rs.Abort();
}
rs = new Thread(SetEvent);
rs.Name = "阻塞读取函数" ;
rs.Start();
ReadDataAndSend(
socket,
e);
}
catch ( Exception ee)
{
OutPut.WriteLine(ee);
}
}
}
/// <summary>
/// 设置线程阻塞
/// </summary>
void SetEvent()
{
waitevent.WaitOne();
}
/// <summary>
/// 读取数据并发送
/// </summary>
/// <param name="socket"></param>
/// <param name="e"></param>
void ReadDataAndSend( Socket socket, SocketAsyncEventArgs e)
{
if (position >= fileinfo.Length)
{
return;
}
byte[] bytes = OperFile.GetFileStream(
fileinfo,
4,
ref readcount,
ref position);
if (bytes == null)
{
return;
}
Socket_ConnectAndSend(socket, bytes, e);
}
/// <summary>
/// 判定接收数据状态
/// </summary>
/// <param name="listreceive"> 接收到的数据 </param>
/// <returns></returns>
HandFileState .HandDataState GetStates( List< byte> listreceive)
{
byte[] statebytes = new byte[1];
if (listreceive.Count == 0 || listreceive == null)
{
return HandFileState .HandDataState .Error;
}
statebytes[0] = listreceive[0];
string _statebytes = Encoding.UTF8.GetString(statebytes, 0, 1);
int state = Convert.ToInt32(_statebytes);
switch (state)
{
case 1:
return HandFileState .HandDataState .HeadPathLoading;
case 2:
return HandFileState .HandDataState .HeadPathFinish;
case 3:
return HandFileState .HandDataState .DataLenLoading;
case 4:
return HandFileState .HandDataState .DatalenFinish;
case 5:
return HandFileState .HandDataState .DataLoading;
case 6:
return HandFileState .HandDataState .DataFinish;
}
return HandFileState .HandDataState .Error;
}
/// <summary>
/// 组装文件路径描述数据包
/// </summary>
/// <returns></returns>
byte[] GetHeadByFilePath()
{
if (fileinfo == null)
{
MessageBox .Show("获取要上传的文件失败!" );
}
string datetime = DateTime.Now.ToString( "yyyyMMddhhmmss" );
string exten = fileinfo.Extension;
StringBuilder path = new StringBuilder ();
path.Append( "^" );
path.Append( "path:" );
path.Append(datetime + exten);
path.Append( "\r\n---------------\r\n" );
path.Append( "^" );
byte[] _path = Encoding.UTF8.GetBytes(path.ToString());
return _path;
}
/// <summary>
/// 组装文件长度描述数据包
/// </summary>
/// <returns></returns>
byte[] GetHeadByDataLen()
{
if (fileinfo == null)
{
MessageBox .Show("获取要上传的文件失败!" );
}
string len = fileinfo.Length.ToString();
StringBuilder lenstr = new StringBuilder ();
lenstr.Append( "^" );
lenstr.Append( "len:" );
lenstr.Append(len);
lenstr.Append( "\r\n---------------\r\n" );
lenstr.Append( "^" );
byte[] _lenstr = Encoding.UTF8.GetBytes(lenstr.ToString());
return _lenstr;
}
}
}