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

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



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yx5131421/archive/2009/08/30/4498414.aspx