读书人

socket 传输资料

发布时间: 2012-12-18 12:43:41 作者: rapoo

socket 传输文件

在两台计算机传输文件之前,必需得先有一台计算机建立套节子连接并绑定一个固定得端口,并在这个端口侦听另外一台计算机的连接请求。

socket?? =?? new?? Socket(AddressFamily.InterNetwork,SocketType.Stream,?? ProtocolType.Tcp);
socket.Blocking?? =?? true?? ;
IPEndPoint?? computernode1?? =?? new?? IPEndPoint(serverIpadress,?? 8080);

socket.Bind(computernode1);

socket.Listen(-1);

当有其他的计算机发出连接请求的时候,被请求的计算机将对每一个连接请求分配一个线程,用于处理文件传输和其他服务。

while?? (?? true?? )??

??? {

??????? clientsock?? =?? socket.Accept();

??????? if?? (?? clientsock.Connected?? )??

??????? {

????????????? Thread?? tc?? =?? new?? Thread(new?? ThreadStart(listenclient));

??????????? tc.Start();

??????? }

??? }

?

下面的代码展示了listenclient方法是如何处理另外一台计算机发送过来的请求。首先并对发送过来的请求字符串作出判断,看看是何种请求,然后决定相应的处理方法。

void?? listenclient()
{
??? Socket?? sock?? =?? clientsock?? ;
??? try
??? {
??????? while?? (?? sock?? !=?? null?? )??
??????? {
??????????? byte[]?? recs?? =?? new?? byte[32767];
??????????? int?? rcount?? =?? sock.Receive(recs,recs.Length,0)?? ;
??????????? string?? message?? =?? System.Text.Encoding.ASCII.GetString(recs)?? ;
????????? //对message作出处理,解析处请求字符和参数存储在cmdList?? 中
??????????????????? execmd=cmdList[0];
??????????? sender?? =?? null?? ;
??????????? sender?? =?? new?? Byte[32767];
???
??????????? string?? parm1?? =?? " ";
//目录列举??????????
if?? (?? execmd?? ==?? "LISTING "?? )??
??????????? {
??????????????? ListFiles(message);
??????????????? continue?? ;
??????????? }??
//文件传输
??????????? if?? (?? execmd?? ==?? "GETOK "?? )
??????????? {
??????????????? cmd?? =?? "BEGINSEND?? "???? +?? filepath?? +?? "?? "?? +?? filesize?? ;
??????????????? sender?? =?? new?? Byte[1024];
??????????????? sender?? =?? Encoding.ASCII.GetBytes(cmd);
??????????????? sock.Send(sender,?? sender.Length?? ,?? 0?? );
????????????????????????????? //转到文件下载处理
??????????????? DownloadingFile(sock);
??????????????? continue?? ;
??????????? }??????
??????? }
??? }
??? catch(Exception?? Se)
??? {
??????? string?? s?? =?? Se.Message;
??????? Console.WriteLine(s);
??? }
}

至此,基本的工作已经完成了,下面我们看看如何处理文件传输的。
while(rdby?? <?? total?? &&?? nfs.CanWrite)
??? {
//从要传输的文件读取指定长度的数据
len?? =fin.Read(buffed,0,buffed.Length)?? ;
??????? //将读取的数据发送到对应的计算机
??????? nfs.Write(buffed,?? 0,len);
??????? //增加已经发送的长度
??????? rdby=rdby+len?? ;????????????????????
??? }
从上面的代码可以看出是完成文件转换成FileStream?? 流,然后通过NetworkStream绑定对应的套节子,最后调用他的write方法发送到对应的计算机。
我们再看看接受端是如何接受传输过来的流,并且转换成文件的:
NetworkStream?? nfs?? =?? new?? NetworkStream(sock)?? ;
try
{
??????????????? //一直循环直到指定的文件长度
??????????????? while(rby?? <?? size)
??? {
??????????? byte[]?? buffer?? =?? new?? byte[1024]?? ;
??????????? //读取发送过来的文件流
??????????? int?? i?? =?? nfs.Read(buffer,0,buffer.Length)?? ;
??????????? fout.Write(buffer,0,(int)i)?? ;
??????????? rby=rby+i?? ;
??????? }????
??? fout.Close()?? ;

从上面可以看出接受与发送恰好是互为相反的过程,非常简单。


//取得预保存的文件名??
string?? fileName= "test.rar ";??
//远程主机??
string?? hostName=TextBoxHost.Text.Trim();??
//端口??
int?? port=80;??
//得到主机信息??
IPHostEntry?? ipInfo=Dns.GetHostByName(hostName);??
//取得IPAddress[]??
IPAddress[]?? ipAddr=ipInfo.AddressList;??
//得到ip??
IPAddress?? ip=ipAddr[0];??
//组合出远程终结点??
IPEndPoint?? hostEP=new?? IPEndPoint(ip,port);??
//创建Socket?? 实例??
Socket?? socket=new?? Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);??
try??
{??
//尝试连接??
socket.Connect(hostEP);??
}??
catch(Exception?? se)??
{??
LeixunCMS.Common.MessageBox.Show(this.Page, "连接错误 "+se.Message);

}

例子2:

这几天一直想写一个类似QQ文件发送的东西,上网找了一些资料,都不是很理想,下面我把我的思路和基本实现代码说下。

???????? 为了把问题说清楚,把一些变量都直接附值了,并没有通过输入附值

????????????????????? 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);

???????????? }

???????????? private void set()???????????????????????//创建set函数
??????? {
??????????? Console.WriteLine("开始发送数据");
??????????? byte[] b = new byte[10000000];??????????? //创建文件缓冲区,这里可以认为文件的最大值
??????????? FileStream file = 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 = 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);
??????????? }
????????? }

读书人网 >编程

热点推荐