C# 多线程阻塞式,网络服务器与客户端(一)

服务器端代码:
实测在阿里云服务器上,无论是先定义好外网IP,还是抓取的外网ip都无法成功监听(本地私网ip也不行)
在使用公网ip时,报错代码上有提及权限问题,推测是跟服务器安全组策略有关(权限问题),
因为在服务器管理页面,在开放端口时,用的也是根权限(0.0.0.0),其他类型的未测试。
猜测直接使用SSH连接服务器,使用Linux命令,关闭防火墙或手动开放端口,也能有类似的效果。

点击查看服务器端代码

using System;
//using System.Management;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Code = System.Text.Encoding;

namespace 服务器1
{
    class Program
    {
        static List<Socket> socketList = new List<Socket>();
        static void Main(string[] args)
        {
            //string ip = GetLocalIp();
            //string publicIp= GetPublicServerIp.GetIP().ToString();
            //Console.WriteLine("publicIp=>" + publicIp);

            Socket tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //tcpSocket.Bind(new IPEndPoint(IPAddress.Parse(publicIp), 49898));   
            //服务器上直接用0.0.0.0即可,否则会报错,即使用的是正确的公网ip
            tcpSocket.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), 49898));
            //tcpSocket.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.xxx"), 9898));

            tcpSocket.Listen(10);
            Console.WriteLine("开始监听");

            //接收客户端连接
            new Thread(() =>
            {
                while (true)
                {
                    Socket clientSocket = tcpSocket.Accept();
                    socketList.Add(clientSocket);
                    Console.WriteLine(clientSocket.RemoteEndPoint + "连接成功!!!现在还有{0}个连接", socketList.Count);

                    new Thread(() =>
                    {
                        try
                        {
                            if (clientSocket != null && clientSocket.Connected)
                            {
                                while (true)
                                {
                                    byte[] buffer = new byte[1024];
                                    int length = clientSocket.Receive(buffer);
                                    string str = Code.UTF8.GetString(buffer, 0, length);
                                    SendToAllClient(str, clientSocket);
                                }
                            }
                        }
                        catch (SocketException)
                        {
                            if (!clientSocket.Connected)
                            {
                                socketList.Remove(clientSocket);
                                Console.WriteLine("客户端{0}已断开连接,现在还有{1}个连接",clientSocket.RemoteEndPoint,socketList.Count);
                            }
                            //Console.WriteLine("SocketException"+ socketList.Count);
                            //Console.WriteLine(socketList.Count);
                        }
                    }).Start();
                }
            }).Start();
            Console.ReadKey();
        }

        /// <summary>
        /// 获取本地局域网ip
        /// </summary>
        /// <returns></returns>
        private static string GetLocalIp()
        {
            IPAddress[] ipArray = Dns.GetHostAddresses(Dns.GetHostName());
            string ip = "";

            for (int i = 0; i < ipArray.Length; i++)
            {
                if (ipArray[i].AddressFamily.ToString() == "InterNetwork")
                {
                    //if (i == ipArray.Length - 1)
                    //{
                    ip = ipArray[i].ToString();
                    Console.WriteLine("V4=>" + ipArray[i]);
                    //}
                }
                else
                {
                    Console.WriteLine("其他=>" + ipArray[i]);
                }
            }

            return ip;
        }

        /// <summary>
        /// 转发给全部客户端
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="clientSocket"></param>
        private static void SendToAllClient(string str, Socket self)
        {
            byte[] buffer = Code.UTF8.GetBytes(str);
            for (int i = 0; i < socketList.Count; i++)
            {
                if (socketList[i] == self) continue;
                socketList[i].Send(buffer);
            }
        }
    }
}


获取本地公网ip代码

点击查看GetPublicServerIp代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace 服务器1
{
    class GetPublicServerIp
    {
        /// <summary>
        /// 获取外网IP
        /// </summary>
        /// <returns></returns>
        public static string GetIP()
        {
            using (var webClient = new WebClient())
            {
                try
                {
                    webClient.Credentials = CredentialCache.DefaultCredentials;
                    byte[] pageDate = webClient.DownloadData("http://pv.sohu.com/cityjson?ie=utf-8");
                    string ip = Encoding.UTF8.GetString(pageDate);
                    webClient.Dispose();

                    Match rebool = Regex.Match(ip, @"\d{2,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}");
                    return rebool.Value;
                }
                catch (Exception )
                {
                    return "";
                }

            }
        }
    }
}

客户端代码
在客户端代码上,要连接上服务器端,则需要正确的公网ip。
或者连接的是局域网,则需要正确的局域网ip,即本机ip。
查看本机ip可通过打开cmd,输入ipconfig命令查看,服务器上好像和这个命令有点差入。

点击查看客户端代码
using System;
using System.Net.Sockets;
using System.Threading;
using Code = System.Text.Encoding;

namespace 客户端1
{
    class Program
    {
        static Socket clientSocket = null;
        static void Main(string[] args)
        {
             clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            //clientSocket.Connect("192.168.0.xxx", 9898);//局域网ip
            clientSocket.Connect("xx.xxx.xxx.xx", 49898);//服务器公网ip
            Console.WriteLine("连接成功!!!");

            //接收信息
            new Thread(()=> {
                while (true)
                {
                    byte[] buffer = new byte[1024];
                    int length = clientSocket.Receive(buffer);
                    string msg = Code.UTF8.GetString(buffer, 0, length);
                    Console.WriteLine(msg);
                }
            }).Start();

            //发送信息
            new Thread(()=> {
                while (true)
                {
                    string str = Console.ReadLine();
                    string msg = clientSocket.LocalEndPoint + ":" + str;
                    byte[] buffer = Code.UTF8.GetBytes(msg);
                    clientSocket.Send(buffer);
                }
            }).Start();
        }
    }
}

本文作者:飞飞吻

本文链接:https://www.cnblogs.com/flyingkisses/p/16021192.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   飞飞吻  阅读(138)  评论(0编辑  收藏  举报
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
点击右上角即可分享
微信分享提示