C#.NET通过Socket实现平行主机之间网络通讯
2010-09-30 22:46:31 来源:WEB开发网RecvPic.cs:
代码
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace ConsoleClientSocketDemo
{
class RecvPic
{
Socket sRecvPic;//接收图片的socket
int recvPicPort;//接收图片端口
public RecvPic(int recvPort)
{
recvPicPort = recvPort;
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, recvPicPort);
sRecvPic = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sRecvPic.Bind(localEndPoint);
sRecvPic.Listen(100);
}
public void thread()
{
while (true)
{
System.Threading.Thread.Sleep(1);//每个线程内部的死循环里面都要加个“短时间”睡眠,使得线程占用资源得到及时释放
try
{
Socket sRecvPicTemp = sRecvPic.Accept();//一直在等待socket请求,并建立一个和请求相同的socket,覆盖掉原来的socket
sRecvPicTemp.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000); //设置接收数据超时
sRecvPicTemp.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 5000);//设置发送数据超时
sRecvPicTemp.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, 1024);//设置发送缓冲区大小--1K大小
sRecvPicTemp.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, 1024); //设置接收缓冲区大小
#region 先取出数据头部信息---并解析头部
byte[] recvHeadBytes = new byte[1024];//先取1K的数据,提取出数据的头部
sRecvPicTemp.Receive(recvHeadBytes, recvHeadBytes.Length, 0);
string recvStr = Encoding.UTF8.GetString(recvHeadBytes);
string[] strHeadArray = recvStr.Split(';');//PicResponse;2;94223;69228;
string strHeadCmd = strHeadArray[0];//头部命令
int picCounts = Convert.ToInt32(strHeadArray[1]) ;//数据流中包含的图片个数
int[] picLength=new int[picCounts];//每个图片的长度
for (int i = 0; i < picCounts;i++ )
{
picLength[i] = Convert.ToInt32(strHeadArray[i+2]);
}
#endregion
int offset=0;//数据头的长度
for (int k = 0; k < strHeadArray.Length - 1;k++ )
{
offset += strHeadArray[k].Length + 1;//因为后面的分号
}
int picOffset = recvHeadBytes.Length - offset;//第一张图片在提取数据头的时候已经被提取了一部分了
if (strHeadCmd == "PicResponse")
{
#region 储存图片--为了节约内存,可以每接收一次就保存一次图片
for (int i = 0; i < picCounts; i++)
{
byte[] recvPicBytes = new byte[(picLength[i])];//每次只接收一张图片
if (i == 0)//第一幅图片有一部分在提取数据头的时候已经提取过了。
{
byte[] recvFirstPicBuffer = new byte[picLength[i] - picOffset];
sRecvPicTemp.Receive(recvFirstPicBuffer, recvFirstPicBuffer.Length, 0);
for (int j = 0; j < picOffset; j++)
{
recvPicBytes[j] = recvHeadBytes[offset + j];//第一幅图片的前一部分
}
for (int j = 0; j < recvFirstPicBuffer.Length; j++)//第一张图片的后半部分
{
recvPicBytes[picOffset + j] = recvFirstPicBuffer[j];
}
//将图片写入文件
SavePicture(recvPicBytes, "-0");
}
else
{
sRecvPicTemp.Receive(recvPicBytes, recvPicBytes.Length, 0);//每次取一张图片的长度
SavePicture(recvPicBytes, "-"+i.ToString());
//将图片数据写入文件
}
}
#endregion
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
finally
{
}
}
}
/// <summary>
/// 保存图片到指定路径
/// </summary>
/// <param name="picBytes">图片比特流</param>
/// <param name="picNum">图片编号</param>
public void SavePicture(byte[] picBytes, string picNum)
{
string filename = "receivePic";
if (!Directory.Exists("E:\\images\\"))
Directory.CreateDirectory("E:\\images\\");
if (File.Exists("E:\\images\\" + filename + picNum + ".jpg"))
return;
FileStream fs = new FileStream("E:\\images\\" + filename + picNum + ".jpg", FileMode.OpenOrCreate, FileAccess.Write);
fs.Write(picBytes, 0, picBytes.Length);
fs.Dispose();
fs.Close();
}
}
}
更多精彩
赞助商链接