zoukankan      html  css  js  c++  java
  • (转载)C#网络通信之TCP连接

     

    基本原理:TCP连接的特点是连接一直存在,即建立连接后可以随时传输数据,直至断开连接为止。TCP连接有着明确的服务器和客户端的分工,因此需要分别编程处理。

           网络通信用到的命名空间:using System.Net;
                                                     using System.Net.Sockets;

           第一步:获取服务器的IP地址

           当然您可以通过ipconfig等方式查询作为服务器的计算机的IP地址,这里介绍通过C#语句获取的方法。

           private String GetIPAddress()
            {
                String str;
                String Result = "";
                String hostName = Dns.GetHostName();
                IPAddress[] myIP = Dns.GetHostAddresses(hostName);
                foreach (IPAddress address in myIP)

                {
                    str = address.ToString();
                    for (int i = 0; i < str.Length; i++)
                    {
                        if (str[i] >= '0' && str[i] <= '9' || str[i] == '.') Result = str;
                    }
                }
                return Result;
            }

           红色的部分是核心的语句,获取的是一组IP地址,存储在 IPAddress[] myIP 中。这组IP地址包含物理(依次输出下就会发现),但我们最常用的是32位的IP地址,因此编写了这个方法进行筛选。

           第二步:服务器建立监听

           IPAddress ipa = IPAddress.Parse("192.168.1.100");

           TcpListener myListener = new TcpListener(ipa, 8080);

           myListener.Start();

           红色的部分是服务器的IP地址和要开放的端口号,视具体情况而定。端口号为整型。

           第三步:客户端请求连接

           TcpClient tclient = new TcpClient();

           tclient.Connect("192.168.1.100", 8080);

           如果客户端请求连接时服务器并未开启监听,则会抛出 SocketException 异常。所以一是要确保服务器开启监听了再请求连接,二是应该把这两行代码放入到try-catch里面,以便连接不成功时程序不会崩溃。

           第四步:服务器应答

           Socket mySocket = myListener.AcceptSocket();

           服务器将连接绑定给mySocket,以后和客户端的通信都通过mySocket来完成。

           但这里需要注意,如果执行该语句时没有客户端请求连接,则会进入无尽的等待,使程序出现“未响应”的状态。因此Socket的下面这个方法将极为有用:

           if (myListener.Pending())
           {
                  Socket mySocket = myListener.AcceptSocket();
            }

           Pending()的作用是“确定是否有挂起的连接请求”,如果有则返回true。这样以来就实现了有请求时才去接受,再配合WinForm的Timer组件使用,可以达到很好的效果。

           至此,连接工作已完成。总结一下,只有第三步是客户端的代码,其余都是服务器的代码。

           第五步:发送数据和接收数据

           1.服务器发送:mySocket.Send(Encoding.Unicode.GetBytes("要发送的内容"));

           2.服务器接收:byte[] data = new byte[1024];
                                   if (mySocket.Available > 0)
                                   {
                                       mySocket.Receive(data);
                                       String content = Encoding.Unicode.GetString(data);
                                   }

           3.客户端发送:NetworkStream ns = tclient.GetStream();

                                   String content = "要发送的内容";

                                   byte[] data = Encoding.Unicode.GetBytes(content);

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

           4.客户端接受:if (tclient.Available > 0)
                                   {
                                       byte[] data = new byte[1024];
                                       ns.Read(data, 0, 1024);
                                       String content = Encoding.Unicode.GetString(data);
                                   }

           服务器使用Send和Receive方法,客户端使用NetworkStream流。其中 mySocket.Available > 0 和 tclient.Available > 0 的作用与 myListener.Pending() 的作用相同,都是先判断是否有数据可读再进行读取,否则也会失去响应。Encoding.Unicode的方法用于字符串和字节数组间的转换,因为网络中的数据是以字节传输的。接收数据时也可以使用Timer来达到更好的效果。

           核心的东西就这么多,具体的应用还要看实际的情况。以上都是我个人总结的,希望对大家有所帮助。

     
  • 相关阅读:
    [LeetCode]130 Surrounded Regions(DFS)
    [LeetCode]233 Number of Digit One(数位DP)
    POJ 3225.Help with Intervals-线段树(成段替换、区间异或、简单hash)
    POJ 2528.Mayor's posters-线段树(成段替换、离散数据、简单hash)
    POJ 3468.A Simple Problem with Integers-线段树(成段增减、区间查询求和)
    HDU 1698.Just a Hook-线段树(成段替换、输出总和tree[1])
    POJ 2886.Who Gets the Most Candies? -线段树(单点更新、类约瑟夫问题)
    计蒜客 28437.Big brother said the calculation-线段树+二分-当前第k个位置的数 ( ACM训练联盟周赛 M)
    HDU 5649.DZY Loves Sorting-线段树+二分-当前第k个位置的数
    计蒜客 28449.算个欧拉函数给大家助助兴-大数的因子个数 (HDU5649.DZY Loves Sorting) ( ACM训练联盟周赛 G)
  • 原文地址:https://www.cnblogs.com/liuxiaowei0543/p/3121423.html
Copyright © 2011-2022 走看看