首页 > 代码库 > Socket学习4 文件传输

Socket学习4 文件传输

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using System.Xml;

 

namespace App_MYCS.HDL_class
{
class my_socketfile
{
private string path = "F:\\SmartMovie.EXE";    //要发送的文件
        private Socket s;    

private void listen()
        {
            string ip = "127.0.0.1";   //远程IP 这里定义为自己的机器
            IPAddress[] ih = Dns.GetHostAddresses(ip); //获得IP列表
            IPAddress newip = ih[0];      //获取IP地址            
            int port = 6789;              //定义端口
        IPEndPoint Conncet = new IPEndPoint(newip, port); //构造结点
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream,  ProtocolType.Tcp);                   //初始化socket 
     try
         {                                  
   s.Connect(Conncet);      //连接远程服务器
  if (s.Connected)   //如果连接成功 s.Connected 则为true 否则为 false
            {
            Console.WriteLine("连接成功");
              Thread t = new Thread(new ThreadStart(set)); //创建线程
                t.Start();                      //开始线程
                Console.WriteLine("发送完毕");     
}
            }catch(NullReferenceException e)
            {
              Console.WriteLine("{0}",e);
            }
}

//创建set函数
private void set()
{
Console.WriteLine("开始发送数据");
byte[] b = new byte[10000000];            //创建文件缓冲区,这里可以认为文件的最大值
FileStream file = System.IO.File.Open(path, FileMode.Open, FileAccess.Read);   //创建文件流
int start = 0;
int end = (int)file.Length;               //获取文件长度 文件传送如果有需要超过int的范围估计就要改写FileStream类了

try
{
while (end != 0)
{
int count = file.Read(b, start, end);      //把数据写进流
start += count;
end -= count;
}
while (start != 0)
{
int n = s.Send(b, end, start, SocketFlags.None);  //用Socket的Send方法发送流
end += n;
start -= n;
}

file.Close();     //关闭文件流
s.Close();        //关闭Socket
}
catch (NullReferenceException e)
{
Console.WriteLine("{0}", e);
}

}
/*
这样文件发送的模型就实现了
接下去实现文件的接收,首先要确定对方发送文件的长度,
* 其实上面的那段还要加入发送文件长度的功能,实现很简单,
* 就是发送int变量end ,然后要求接收代码返回一个Boolean确定是否发送,
* 这里为了更简明的说清楚原理并没有实现
            
*/

private void get()
{
string path = "G:\\da.exe";  //接收的文件
FileStream file = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write); //写入文件流
TcpListener listen = new TcpListener(6789);  //监听端口
Socket s1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  //定义Socket并初始化
try
{
listen.Start();        //开始监听
s1 = listen.AcceptSocket();            //获取Socket连接
byte[] data = http://www.mamicode.com/new byte[10000000]; //定义缓冲区
int longer = data.Length;
int start = 0;
int mid = 0;
if (s1.Connected)             //确定连接
{
Console.WriteLine("连接成功");
int count = s1.Receive(data, start, longer, SocketFlags.None);  //把接收到的byte存入缓冲区
mid += count;
longer -= mid;
while (count != 0)
{
count = s1.Receive(data, mid, longer, SocketFlags.None);
mid += count;
longer -= mid;
}
file.Write(data, 0, 1214134); //写入文件,1214134为文件大小,可以用socket发送获得,代码前面已经说明。
s1.Close();
file.Close();
}
}
catch (NullReferenceException e)
{
Console.WriteLine("{0}", e);
}

}

class my_sockets
{
string _responseStr;
///   <summary>
///   GET方式发送请求
///   </summary>
///   <param   name= "requestUrl "> 请求地址 </param>
///   <returns> 响应字符串 </returns>
public string SendRequest(string requestUrl)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
httpWebRequest.Method = "GET ";
WebResponse webResponse = httpWebRequest.GetResponse();
StreamReader responseStream = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.UTF8);
_responseStr = responseStream.ReadToEnd();
webResponse.Close();
responseStream.Close();
return _responseStr;
}


///   <summary>
///   Class1   的摘要说明。
///   </summary>
//   RequestState   类用于通过
//   异步调用传递数据
public class RequestState
{
const int BUFFER_SIZE = 1024;
public StringBuilder RequestData;
public byte[] BufferRead;
public HttpWebRequest Request;
public Stream ResponseStream;
//   创建适当编码类型的解码器
public Decoder StreamDecode = Encoding.Default.GetDecoder();

public RequestState()
{
BufferRead = new byte[BUFFER_SIZE];
RequestData = http://www.mamicode.com/new StringBuilder(" ");
Request = null;
ResponseStream = null;
}
}

//   ClientGetAsync   发出异步请求
public static ManualResetEvent allDone = new ManualResetEvent(false);
const int BUFFER_SIZE = 1024;
public static void Main(string[] args)
{
//修改或给此字符串作循环,以连续的发送和接受数据流
string HttpUrl = "http://211.154.223.116:3000/tysy.jsp?CorpID=1&Phone=13012345678&Data=http://www.mamicode.com/17200310101";
//   从命令行获取   URI
Uri HttpSite = new Uri(HttpUrl);

//   创建请求对象
HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(HttpSite);

//   创建状态对象
RequestState rs = new RequestState();

//   将请求添加到状态,以便它可以被来回传递
rs.Request = wreq;

//   发出异步请求
IAsyncResult r = (IAsyncResult)wreq.BeginGetResponse(new AsyncCallback(RespCallback), rs);

//   将   ManualResetEvent   设置为   Wait,
//   以便在调用回调前,应用程序不退出
allDone.WaitOne();
}

private static void RespCallback(IAsyncResult ar)
{
//   从异步结果获取   RequestState   对象
RequestState   rs   =   (RequestState)   ar.AsyncState;

//   从   RequestState   获取   HttpWebRequest  
HttpWebRequest   req   =   rs.Request;

//   调用   EndGetResponse   生成   HttpWebResponse   对象
//   该对象来自上面发出的请求
HttpWebResponse   resp   =   (HttpWebResponse)   req.EndGetResponse(ar);

//   既然我们拥有了响应,就该从
//   响应流开始读取数据了
Stream   ResponseStream   =   resp.GetResponseStream();

//   该读取操作也使用异步完成,所以我们
//   将要以   RequestState   存储流
rs.ResponseStream   =   ResponseStream;

//   请注意,rs.BufferRead   被传入到   BeginRead。
//   这是数据将被读入的位置。
IAsyncResult   iarRead   =   ResponseStream.BeginRead(rs.BufferRead,   0,   BUFFER_SIZE,   new   AsyncCallback(ReadCallBack),   rs);
}


private static void ReadCallBack(IAsyncResult asyncResult)
{
//   从   asyncresult   获取   RequestState   对象
RequestState rs = (RequestState)asyncResult.AsyncState;

//   取出在   RespCallback   中设置的   ResponseStream
Stream responseStream = rs.ResponseStream;

//   此时   rs.BufferRead   中应该有一些数据。
//   读取操作将告诉我们那里是否有数据
int read = responseStream.EndRead(asyncResult);

if (read > 0)
{
//   准备   Char   数组缓冲区,用于向   Unicode   转换
Char[] charBuffer = new Char[BUFFER_SIZE];

//   将字节流转换为   Char   数组,然后转换为字符串
//   len   显示多少字符被转换为   Unicode
int len = rs.StreamDecode.GetChars(rs.BufferRead, 0, read, charBuffer, 0);
String str = new String(charBuffer, 0, len);

//   将最近读取的数据追加到   RequestData   stringbuilder   对象中,
//   该对象包含在   RequestState   中
rs.RequestData.Append(str);


//   现在发出另一个异步调用,读取更多的数据
//   请注意,将不断调用此过程,直到  
//   responseStream.EndRead   返回   -1
IAsyncResult ar = responseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
}
else
{
if (rs.RequestData.Length > 1)
{
//   所有数据都已被读取,因此将其显示到控制台
string strContent;
strContent = rs.RequestData.ToString();

//Console.WriteLine(strContent.Trim().ToString());

string MsgData = "http://www.mamicode.com/Phone=" + MidStr("phone ", strContent) + "\n " + "Data= "http://www.mamicode.com/+ MidStr("data ", strContent) + "\n " + "Data-Id= " + MidStr("data-id ", strContent);

Console.WriteLine(MsgData.ToString());

//==================================以XML方式处理流时,有问题.所以我把返回值当字符串处理的==============================
// XmlNodeReader   nreader   =   null;
// try
// {
// XmlDocument   exampledoc   =   new   XmlDocument();
// exampledoc.Load(strContent.Trim().ToString());
// XmlNode   name   =   exampledoc.SelectSingleNode
// ( "/csjx-service/data ");     ///单个读取节点值
// if(name!=   null)
// {
// nreader   =   new   XmlNodeReader(name);
// while(nreader.Read())
// {
// Console.Write   (nreader.Value);
// Console.Write   (nreader.Name+ "   ");
// }
// }
// }
// finally
// {
// if(nreader!=null)
// nreader.Close();
// }
}

//   关闭响应流
responseStream.Close();

//   设置   ManualResetEvent,以便主线程可以退出
allDone.Set();
}
return;
}
///   <summary>
///   返回两个字符串节点之间的字符串
///   </summary>
///   <param   name= "NodeStr "> 字符节点 </param>
///   <param   name= "StreamStr "> 数据流 </param>
///   <returns> 返回的提取的字符串 </returns>
public static string MidStr(string NodeStr, string StreamStr)
{
int StarStr = (StreamStr.Trim()).IndexOf(" < " + NodeStr.Trim() + "> ");
int StopStr = (StreamStr.Trim()).IndexOf(" </ " + NodeStr.Trim() + "> ");
string MidStr = (StreamStr.Trim()).Substring(StarStr + NodeStr.Length + 2, StopStr - StarStr - NodeStr.Length - 2);
return MidStr;
}
}

}

Socket学习4 文件传输