用Socket传输200-500M的文件解决方案,有代码

huangjinyin 2008-01-20 05:03:01
/// <summary>
/// 将文件写到Socket
/// </summary>
/// <param name="s">要发送文件的Socket</param>
/// <param name="strFile">要发送的文件</param>
/// <returns>是否成功</returns>
public static bool WriteFileToSocket(Socket s, string strFile,OnSend OnSendFile)
{

FileStream fs = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.Read);
int iLen = (int)fs.Length;
WriteDynamicLenToSocket(s, iLen);
byte[] buf = new byte[iLen];
try
{
fs.Read(buf, 0, iLen);
return WriteBufToSocket(s, buf, 0, iLen, DEALLEN, OnSendFile);
}
catch (Exception err)
{

MessageBox.Show("1发送文件失败!" + err.Message);
return false;

}
finally
{
fs.Close();
}

}
/// <summary>
/// 将缓存的指定部分发送到Socket
/// </summary>
/// <param name="s">要发送缓存的Socket</param>
/// <param name="buf">要发送的缓存</param>
/// <param name="iStart">要发送缓存的起始位置</param>
/// <param name="iCount">要发送缓存的字节数</param>
/// <param name="iBlock">每次发送的字节数</param>
/// <param name="SendSuccess">每次发送成功后的回调函数</param>
/// <returns>是否发送成功</returns>

public static bool WriteBufToSocket(Socket s, byte[] buf, int iStart, int iCount, int iBlock, OnSend SendSuccess)
{

int iSended = 0;

int iSending = 0;

while (iSended < iCount)
{

if (iSended + iBlock <= iCount)

iSending = iBlock;

else

iSending = iCount - iSended;

s.Send(buf, iStart + iSended, iSending, SocketFlags.None);

iSended += iSending;

if (ReadResponsionFromSocket(s) == "OK")

if (SendSuccess != null)

SendSuccess(iCount, iSended);

else

return false;

}

return true;

}
/// <summary>
/// 大文件发送时使用,
/// </summary>
/// <param name="s"></param>
/// <param name="strFile"></param>
/// <param name="OnSendFile"></param>
/// <returns></returns>
public static bool WriteBigFileToSocket(Socket s, string strFile,OnSend OnSendFile)
{

FileStream fs = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.Read);

int iLen = (int)fs.Length;

WriteDynamicLenToSocket(s, iLen);

byte[] buf = new byte[FILEBLOCK];


int len;

try
{
while ((len = fs.Read(buf, 0, FILEBLOCK)) != 0)
{
s.Send(buf, 0, len, SocketFlags.None);
}
fs.Close();
// fs.Read(buf, 0, iLen);

// return WriteBufToSocket(s, buf, 0, iLen, DEALLEN, OnSendFile);
return true;
}

catch (Exception err)
{

MessageBox.Show("发送大文件失败!" + err.Message);

return false;

}

finally
{

fs.Close();
buf = new byte[0];
}

}
以上是发送部分
/// <summary>
/// 读取文件形式的可变信息
/// </summary>
/// <param name="s">要读取可变信息的Socket</param>
/// <param name="strFile">读出后的文件保存位置</param>
/// <returns>是否读取成功</returns>

public static bool ReadDynamicFileFromSocket(Socket s, string strFile)
{

int iLen = ReadDynamicLenFromSocket(s);

byte[] buf = new byte[iLen];

FileStream fs = new FileStream(strFile, FileMode.Create, FileAccess.Write);



try
{

int iReceiveded = 0;

int iReceiveing = 0;

while (iReceiveded < iLen)
{

if (iReceiveded + DEALLEN <= iLen)

iReceiveing = DEALLEN;

else

iReceiveing = iLen - iReceiveded;

s.Receive(buf, iReceiveded, iReceiveing, SocketFlags.None);

CommonClass.WriteTextToSocket(s, "OK");

iReceiveded += iReceiveing;

}

fs.Write(buf, 0, iLen);

return true;

}

catch (Exception err)
{

MessageBox.Show("接收文件失败" + err.Message);
return false;

}

finally
{

fs.Close();

}

}

/// <summary>
/// 读取文件形式的可变信息
/// </summary>
/// <param name="s">要读取可变信息的Socket</param>
/// <param name="strFile">读出后的文件保存位置</param>
/// <returns>是否读取成功</returns>
public static bool ReadBigFileFromSocket(Socket s, string strFile)
{

int iLen = ReadDynamicLenFromSocket(s);
byte[] buf = new byte[FILEBLOCK];

FileStream fs = new FileStream(strFile, FileMode.Create, FileAccess.Write);
try
{
int iReceiveded = 0;
int iReceiveing = 0;

while (iReceiveded < iLen)
{
if (iReceiveded + FILEBLOCK <= iLen)

iReceiveing = FILEBLOCK;

else

iReceiveing = iLen - iReceiveded;

s.Receive(buf, 0, iReceiveing, SocketFlags.None);
//分块写入到文件
fs.Write(buf, 0, iReceiveing);
// CommonClass.WriteTextToSocket(s, "OK");
iReceiveded += iReceiveing;

}
//fs.Write(buf, 0, iLen);
return true;
}
catch (Exception err)
{
MessageBox.Show("接收文件失败" + err.Message);
return false;
}
finally
{
fs.Close();
}
}
private static readonly int DEALLEN = 4096 ;
这是接收部分,
这个用来接收十几M的文件没有问题,但是接收三十M以上的不会出错,高手分析一下是什么原因
如有DEMO希望能发一份给我:huangjinyin66@163.com
...全文
171 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzh4818 2008-07-22
  • 打赏
  • 举报
回复
up ding
zmacro 2008-01-21
  • 打赏
  • 举报
回复
up
huangjinyin 2008-01-21
  • 打赏
  • 举报
回复
下面还有个函数是分段分包发送的
cangwu_lee 2008-01-20
  • 打赏
  • 举报
回复

沒有分段(分包)發送?夠嗆了。




fish_yht 2008-01-20
  • 打赏
  • 举报
回复
up
wopos 2008-01-20
  • 打赏
  • 举报
回复
upup
huangjinyin 2008-01-20
  • 打赏
  • 举报
回复
但是接收三十M以上的会出错

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧