源代码下载:http://download.csdn.net/download/hulele2009/6487643
1,如何发送文件,选用网络协议
能满足我们需求的协议是比较多的,UDP协议,TCP/IP协议,HTTP协议,由于TCP/IP协议的安全可靠,我选用TCP/IP协议,UDP虽然传输效率高,但不安全,也不是一种面向连接的,他并不能保证先发的数据就能先到,也不能保证发送的数据就能送到目的,所以不可靠.HTTP协议虽然可靠,但是他是超文本协议,基于TCP/IP协议,没有TCP/IP高效.所以我选用TCP/IP协议来作为首选.
2,数据包组合
我们要通过网络发送一个文件时,因为是面向流的.所以首先要考虑的是,发送过去,对方接收方如何识别,接收方如何知道那一部分是文件名,那一部分是文件内容,所以我们要考虑的方式是:以定长来确定不定长.文件的大小是不固定的,文件名的长度是不固定的.所以发送一个文件就要按照以下几个步骤:
1,发送文件名的长度. 我们用意个long来表示文件名的长度,8个字节固定的
2,发送文件名的内容.
3,发送文件的长度 ,用long 8个固定的字节来表示文件内容的长度
4,发送文件的内容
3,接收方如何接收
1,接收文件名的长度
2,接收文件名的内容(根据上一步接收到的文件名的长度,我们就可以知道哪些字节代表的是文件的内容,)
3,接收文件长度
4,接收文件内容
4.用一个图来表示文件的发送和接收
5,C#编写一个winform程序发送图片,另一winform程序接收图片,接收后不保存,直接从将内存中的图片对象显示到窗体上,下边是接收和发送的核心代码,
下边是接收程序winform的核心代码:
- private void Form1_Load(object sender, EventArgs e)
- {
- //为了不使主窗口线程阻塞
- //在窗体的加载事件中,创建一个线程,专门用来接收图片
- Control.CheckForIllegalCrossThreadCalls = true;
- Thread th = new Thread(new ThreadStart(RC));
- th.Start();
- th.Join();
- }
-
- public void RC()
- {
- /************************************************************************/
- /* 接收方为服务器端,监听,等待客户端发送图片,并作显示 */
- /************************************************************************/
- Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- EndPoint point = new IPEndPoint(IPAddress.Any, 10000);
- sock.Bind(point);
- sock.Listen(10);
-
- while (true)
- {
- Socket client = sock.Accept();
- byte[] bitLen=new byte[8];
- client.Receive(bitLen,bitLen.Length,SocketFlags.None);
- //第一步接收文件的大小
- long contentLen = BitConverter.ToInt64(bitLen,0);
- int size = 0;
- MemoryStream ms = new MemoryStream();
- //循环接收文件的内容,如果接收完毕,则break;
- while (size<contentLen)
- {
- //分多次接收,每次接收256个字节,
- byte[] bits = new byte[256];
- int r = client.Receive(bits, bits.Length, SocketFlags.None);
- if (r <= 0) break;
- ms.Write(bits,0,r);
- size += r;
- }
- client.Close();
- //接收到就显示,然后关闭当前连接,继续监听
- wangle(ms);
- }
-
- }
- public void wangle(MemoryStream ms)
- {
- Image img = Image.FromStream(ms);
- picBox.Image = null;
- picBox.Image = img;
- }
以下代码是发送文件图片文件的核心代码:
- public partial class Form1 : Form
- {
- static Stream fs = null;
- int nameLen = 0;
- List<byte> name;
- long contentLen = 0;
- List<byte> content;
- public Form1()
- {
- InitializeComponent();
- }
-
- private void btnSend_Click(object sender, EventArgs e)
- {
- //实例化一个基于TCP/IP的基于流的套接字
- Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- EndPoint endPoint = new IPEndPoint(IPAddress.Parse("192.168.0.4"), 10000);
- sock.Connect(endPoint);
- //组建数据包
- //文件长度
- contentLen = fs.Length;
- //文件内容
- sock.Send(BitConverter.GetBytes(contentLen));
- //循环发送文件内容
- while (true)
- {
- byte[] bits = new byte[256];
- int r = fs.Read(bits, 0, bits.Length);
- if (r <= 0) break; //如果从流中读取完毕,则break;
- sock.Send(bits, r, SocketFlags.None);
- }
- sock.Close();
- //由于读取操作会是文件指针产生偏移,最后读取结束之后,要将指针置为0;
- fs.Position = 0;
- }
-
- private void btnBrowser_Click(object sender, EventArgs e)
- {
- OpenFileDialog dlg = new OpenFileDialog();
- dlg.Filter = "只能发送图片文件|*.png;*.jpg;*.gif|All Files|*.*";
- if (DialogResult.OK == dlg.ShowDialog())
- {
- fs = dlg.OpenFile();
- txtPath.Text = dlg.FileName;
- //文件名长度
- nameLen = Path.GetFileName(dlg.FileName).Length;
- //文件名内容
- Encoding encoding = new UTF8Encoding();
- //将文件名转换为字节
- name = encoding.GetBytes(Path.GetFileName(dlg.FileName)).ToList();
- }
- }
-
- //利用下边的代码可以实时的将桌面截图发给远方,实现桌面的远程监控
- private void Form1_Load(object sender, EventArgs e)
- {
- //获取主屏
- Screen s = Screen.PrimaryScreen;
- //创建一个位图,将其大小设置为何屏幕大小一致,为了获取屏幕的图片
- Bitmap bit = new Bitmap(s.Bounds.Width,s.Bounds.Height);
- //利用当前bit获取一个画布,画布已经于Graphics对象关联
- Graphics g = Graphics.FromImage(bit);
- //将屏幕的(0,0)坐标截图内容copy到画布的(0,0)位置,尺寸到校 bit.size;
- g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bit.Size);
- //将位图保存到D盘
- bit.Save("D:\\123.jpg");
- //释放位图资源
- bit.Dispose();
- //释放画布
- g.Dispose();
- }
- }
源代码下载:示例程序下载
注:利用上边的方式也可以实现远程桌面的实时监控,实时的发送图片到接收端,显示;
|