登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

天道酬勤 玩物丧志

用勇气去改变可以改变的事情,用胸怀去包容无法改变的事情,用智慧去判断两者的区别

 
 
 

日志

 
 

socket与TcpListener/TcpClient/UdpClient 的区别及联系  

2011-07-06 23:42:17|  分类: C#文件网络传输 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

应用程序可以通过 TCPClient、TCPListener 和 UDPClient 类使用传输控制协议 (TCP) 和用户数据文报协议 (UDP) 服务。这些协议类建立在 System.Net.Sockets.Socket 类的基础之上,负责数据传送的细节。(也就是说TCPClient、TCPListener 和 UDPClient 类是用来简化Socket)

    TcpClient 和 TcpListener 使用 NetworkStream 类表示网络。使用 GetStream 方法返回网络流,然后调用该流的 Read 和 Write 方法。NetworkStream 不拥有协议类的基础套接字,因此关闭它并不影响套接字。

    UdpClient 类使用字节数组保存 UDP 数据文报。使用 Send 方法向网络发送数据,使用 Receive 方法接收传入的数据文报。

1.TcpClient
    TcpClient
类提供了一些简单的方法,用于在同步阻止模式下通过网络来连接、发送和接收流数据。为使 TcpClient 连接并交换数据,使用 TCP ProtocolType 创建的 TcpListenerSocket 必须侦听是否有传入的连接请求。可以使用下面两种方法之一连接到该侦听器:
   (1)创建一个 TcpClient,并调用三个可用的 Connect 方法之一。
   (2)使用远程主机的主机名和端口号创建 TcpClient。此构造函数将自动尝试一个连接。
    给继承者的说明要发送和接收数据,请使用 GetStream 方法来获取一个 NetworkStream。调用 NetworkStream 的 WriteRead 方法与远程主机之间发送和接收数据。使用 Close 方法释放与 TcpClient 关联的所有资源。

    下面的例子给出怎么利用TcpClient连接到服务器:

using System;

using System.Collections.Generic;

using System.Text;

using System.Net.Sockets;

using System.Net;

 

namespace tcpclient

{

    classProgram

    {

        privatestaticint portNum = 11000;

        privatestaticstring hostName = Dns.GetHostName().ToString();

        publicstaticvoid Main(String[] args)

        {

            try

            {

                Console.WriteLine("主机名字:"+ Dns.GetHostName());

                Console.WriteLine("主机IP地址:"+ Dns.GetHostAddresses(Dns.GetHostName())[0]);

               TcpClient client = newTcpClient(hostName, portNum);

                NetworkStream ns = client.GetStream();

                byte[] bytes = newbyte[1024];

                int bytesRead = ns.Read(bytes, 0, bytes.Length);

                //将字节流解码为字符串

                Console.WriteLine(Encoding.ASCII.GetString(bytes, 0, bytesRead));

                client.Close();

            }

            catch (Exception e)

            {

                Console.WriteLine(e.ToString());

            }

    

        }

    }

}

2.TcpListener
   TcpListener
类提供一些简单方法,用于在阻止同步模式下侦听和接受传入连接请求。可使用 TcpClientSocket 来连接 TcpListener。可使用 IPEndPoint、本地 IP 地址及端口号或者仅使用端口号,来创建 TcpListener。可以将本地 IP 地址指定为 Any,将本地端口号指定为 0(如果希望基础服务提供程序为您分配这些值)。如果您选择这样做,可在连接套接字后使用 LocalEndpoint 属性来标识已指定的信息。

    Start方法用来开始侦听传入的连接请求。Start 将对传入连接进行排队,直至您调用 Stop 方法或它已经完成 MaxConnections 排队为止。可使用 AcceptSocketAcceptTcpClient 从传入连接请求队列提取连接。这两种方法将阻止。如果要避免阻止,可首先使用 Pending 方法来确定队列中是否有可用的连接请求。

调用 Stop 方法来关闭 TcpListener。

下面的例子给出怎么利用TcpListener监听客户端的请求:
using System;

using System.Collections.Generic;

using System.Text;

using System.Net.Sockets;

using System.Net;

namespace tcpclient

{

    classProgram

    {

        privateconstint portNum = 11000;

        staticvoid Main(string[] args)

        {

            bool done = false;

            //TcpListener listener = new TcpListener(portNum); //根据VS2005 MSDN 此方法已经过时,不再使用

            // IPEndPoint类将网络标识为IP地址和端口号

            TcpListener listener = newTcpListener(newIPEndPoint(IPAddress.Any, portNum));

            listener.Start();

            while (!done)

            {

                Console.Write("Waiting for connection...");

                TcpClient client = listener.AcceptTcpClient();

                Console.WriteLine("Connection accepted.");

                NetworkStream ns = client.GetStream();

                byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());

                try

                {

                    ns.Write(byteTime, 0, byteTime.Length);

                    ns.Close();

                    client.Close();

                }

                catch (Exception e)

                {

                    Console.WriteLine(e.ToString());

                }

            }

            listener.Stop();

         }

    }

}

 

3.UdpClient
   UdpClient
类提供了一些简单的方法,用于在阻止同步模式下发送和接收无连接 UDP 数据报。因为 UDP 是无连接传输协议,所以不需要在发送和接收数据前建立远程主机连接。但您可以选择使用下面两种方法之一来建立默认远程主机:

·         使用远程主机名和端口号作为参数创建 UdpClient 类的实例。

·         创建 UdpClient 类的实例,然后调用 Connect 方法。

   可以使用在 UdpClient 中提供的任何一种发送方法将数据发送到远程设备。使用 Receive 方法可以从远程主机接收数据。
   UdpClient 方法还允许发送和接收多路广播数据报。使用 JoinMulticastGroup 方法可以将 UdpClient 预订给多路广播组。使用 DropMulticastGroup 方法可以从多路广播组中取消对 UdpClient 的预订。

   下面的例子演示同一主机不同端口之间的UDP通信:

监听端:
using System;

using System.Net.Sockets;

using System.Text;

using System.Net;

using System.Threading;

namespace Udpclient2

{

    classProgram

    {

        staticvoid Main(string[] args)

        {

            try

            {

                UdpClient udpClient = newUdpClient(12000);

                string returnData = "client_end";

                do

                {

                    Console.WriteLine("服务器端接收数据:.............................");

                    IPEndPoint RemoteIpEndPoint = newIPEndPoint(IPAddress.Any, 0);

                    // 此处通过引用传值,获得客户端的IP地址及端口号

                    Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);

                    //此处获得客户端的数据

                    returnData = Encoding.UTF8.GetString(receiveBytes);

                    //Encoding.ASCII.GetString(receiveBytes); 此处若用ASCII,不能正确处理中文

                    Console.WriteLine("This is the message server received: " + returnData.ToString());

 

                    Thread.Sleep(3000);

                

                    Console.WriteLine("向客户端发送数据:.............................");

                    udpClient.Connect(Dns.GetHostName().ToString(), 11000);

                    // Sends a message to the host to which you have connected.

                    string sendStr = "我来自服务器端:" + DateTime.Now.ToString();

                    Byte[] sendBytes = Encoding.UTF8.GetBytes(sendStr);

                    //Byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr); 此处若用ASCII,不能正确处理中文

                    udpClient.Send(sendBytes, sendBytes.Length);

                    Console.WriteLine("This is the message server send: " + sendStr);

 

                 } while (returnData != "client_end");

               

            }

            catch (Exception e)

            {

                Console.WriteLine(e.ToString());

            }

        }

    }

}

 

客户端:
using System;

using System.Net.Sockets;

using System.Text;

using System.Net;

namespace Udpclient

{

    classProgram

    {

        staticvoid Main(string[] args)

        {

           try

            {

               UdpClient udpClient = newUdpClient(11000);

              

               //向服务器发送数据

               udpClient.Connect(Dns.GetHostName().ToString(), 12000);

               // Sends a message to the host to which you have connected.

               string sendStr = "我来自客户端:" + DateTime.Now.ToString();

               Byte[] sendBytes = Encoding.UTF8.GetBytes(sendStr);

               //Byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr); 此处若用ASCII,不能正确处理中文

               udpClient.Send(sendBytes, sendBytes.Length);

               Console.WriteLine("This is the message client send: " + sendStr);

               

              

               //等待服务器的答复,收到后显示答复,并结束对话

               IPEndPoint RemoteIpEndPoint = newIPEndPoint(IPAddress.Any, 0);

               // 此处通过引用传值,获得客户端的IP地址及端口号

               Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);

               //此处获得服务器端的数据

               string returnData = Encoding.UTF8.GetString(receiveBytes);

               //Encoding.ASCII.GetString(receiveBytes); 此处若用ASCII,不能正确处理中文

               Console.WriteLine("This is the message come from server: " + returnData.ToString());

               udpClient.Close();

            }

            catch (Exception e)

            {

                Console.WriteLine(e.ToString());

            }

        }

    }

}


 

参考:http://hi.baidu.com/2zhyi/blog/item/84d2c8f2dc6eb449342accb3.html

  评论这张
 
阅读(688)| 评论(0)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018