C# Socket编程实践2

​​​​​​​​​​​​C# Socket编程实践1

目标

  1. 用Socket完成服务器代码的编写,能够实现接收客户端的请求,并返回"I've received the msg."已完成
  2. 用Socket完成客户端代码的编写,能够实现向服务端发送请求。已完成
  3. 实现客户端、服务端双向通信(将服务端发送的内容,改成从界面获取就好了。这样就是一个点对点的了。 String s = Console.ReadLine();// 等待用户输入)。本节目标
  4. 简单放上我之前的关于线程的简单测试吧。线程基本
  5. 实现服务端响应多个客户端,加入了线程。本节目标
  6. 将Socket请求可以封装起来,后续就可以减少一些重复代码
  7. 实现聊天的功能
  8. 待开发。。。

准备工作 

  • Windows 10 2016 64位
  • VS 2019
  • using System.Text; Encoding
  • using System.Net; IPAddress
  • using System.Net.Sockets; Socket
  • using System.Threading; Thread

带System的命名空间一般是vs自带的,只要你安装的时候选了,大多都会自带。 

代码

服务端

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace MyServer
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // 1.使用http协议建立连接
                Socket listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                listen.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8899));
                listen.Listen(3);// 从0开始计数,也就是可以连接4个客户端
                Console.WriteLine("The server is listening...");


                 2.使用死循环持续接收客户端连接请求(我的连接请求限制是3个 listen.Listen(3);)
                 点对点不需要这个循环,因为接受来自客户端的请求也需要开辟新的线程去处理
                ///  监听数最好限制在1个,因为没有开辟线程去处理吧
                while (true)
                {
                    Socket client = listen.Accept();
                    Console.WriteLine("the connection from {0}", client.RemoteEndPoint);

                    // 3.使用线程,在线程里死循环用socket协议进行持续通信(write,read;send,receive)
                    // 在做這一步之前,先了解一下線程是如何使用的 4 ways to create a thread
                    // 當然你直接照我下面那樣寫也是沒有問題的
                    // a. static method(靜態方法)
                    // b. instance(实例)
                    // c. delegate(委託)
                    // d. lambda(表達式)


                    // 使用线程
                    Thread thLambda = new Thread((object cc) =>
                    {
                        Socket thc = (Socket)cc;
                        while (true)
                        {
                            byte[] re = new byte[1024];
                            // 捕獲 客戶端強制關閉時引發的異常,讓程序能正常運行,不意外關閉
                            try
                            {
                                // 等待客戶端輸入
                                // 當客戶端斷開鏈接,此處會報錯:遠端主機[客戶端]已強制關閉一個現存的連線。
                                thc.Receive(re);//在这里等待客户端的输入,并将输入的内容存到 re 里
                            }
                            catch (Exception ex)
                            {
                                thc.Close();
                                Console.WriteLine("[{0}]{1}", client.RemoteEndPoint,ex.Message);
                                break;
                            }

                            Console.WriteLine("From client[{1}]:{0}", Encoding.UTF8.GetString(re), client.RemoteEndPoint);

                            // 固定发送数据
                            // 升级版本为指定发给某一客户端,需要存储连接进来的套接字,下个版本用窗体写吧。
                            thc.Send(Encoding.UTF8.GetBytes("I've received the message."));
                        }
                    });
                    thLambda.Start(client);
                    Console.WriteLine("The thread is start.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                Console.WriteLine("Error{0}\r{1}", ex.Message, ex.StackTrace);
            }

        }
    }
}

客户端

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;


namespace MyClient
{
    class Program
    {
        /// <summary>
        /// Socket 第一次建立连接(向服务器发起请求)的时候,使用的是http协议
        ///        连接成功后,使用socket协议进行交流(双向交流,类似QQ)。
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            try
            {
                // 1.使用http协议建立连接
                Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8899));

                if (client.Connected)
                    Console.WriteLine("You guys can chat now!");


                // 2.使用死循环用socket协议进行持续通信(write,read;send,receive)
                while (true)
                {
                    String s = Console.ReadLine();// 等待用户输入

                    if (s == "bye")
                        break;

                    // 向服务器发送用户输入的数据
                    // 与服务器进行通信
                    int len = client.Send(Encoding.UTF8.GetBytes(s));

                    // 接收服务器返回的数据
                    byte[] re = new byte[1024];
                    int ire = client.Receive(re);
                    Console.WriteLine("Form server:{0}", Encoding.UTF8.GetString(re));
                }

                client.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                Console.WriteLine("Error....{0}\r{1}", ex.Message, ex.StackTrace);
            }

            Console.ReadLine();
        }



    }
}

效果

 参考文章:系列文章c#Socket通讯WebSocket和Socket

猜你喜欢

转载自blog.csdn.net/qq_41128526/article/details/124198635