C# 简单 Socket编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012278016/article/details/90958251

客户端:

ClientControl.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ExampleNetCilent
{
    public class ClientControl
    {
        private Socket clientSocket;

        public ClientControl()
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建客户端socket
        }

        public void connect(string ip, int port)
        {
            clientSocket.Connect(ip, port);//连接服务器
            Console.WriteLine("连接服务器成功");


            Thread threadReceive = new Thread(receive); //创建新线程接收消息
            threadReceive.IsBackground = true; //该线程后台运行
            threadReceive.Start(); //启动线程
        }

        //接收服务器端发来的消息
        private void receive()
        {
            while(true)
            {
                try
                {
                    byte[] msg = new byte[1024];
                    int msgLen = clientSocket.Receive(msg); //接收消息 字节数组 返回值为接收的字节长度
                    Console.WriteLine("服务器说: " + Encoding.UTF8.GetString(msg, 0, msgLen)); //转换字节为字符串输出
                }
                catch
                {
                    Console.WriteLine("服务器积极拒绝");
                    break;
                }
            }
        }

        public void send()
        {
            Thread threadSend = new Thread(readAndSend); //创建新线程 发送消息
            //threadSend.IsBackground = true;  //取消后台执行 为了避免主线程关闭 子线程也关闭
            threadSend.Start();
        }

        //读取用户输入并发送
        private void readAndSend()
        {
            Console.WriteLine("请输入要发送的内容,输入quit退出");

            string msg = Console.ReadLine();
            while (msg != "quit")
            {
                clientSocket.Send(Encoding.UTF8.GetBytes(msg)); //发消息 Send函数 接受字节数组   msg 转字节数组 进行发送
                msg = Console.ReadLine();
            }
        }
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace ExampleNetCilent
{
    class Program
    {
        static void Main(string[] args)
        {

            ClientControl client = new ClientControl();
            client.connect("127.0.0.1", 12321);//链接服务器

            client.send(); //发送消息

            Console.ReadKey();
        }

    }
}

服务器端:

ServerControl.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ExampleNetServer
{
    public class ServerControl
    {
        private Socket serverSocket;
        private List<Socket> clientList;

        public ServerControl()
        {
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建服务器端socket  ipv4, 流式传输,  tcp协议
            clientList = new List<Socket>();
        }

        public void start()
        {
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 12321)); //绑定IP 及 端口 IPAddress.Any 表示程序运行在的机器IP地址 也可以为IPAddress.Parse("192.168.0.3")   
            serverSocket.Listen(10);// 监听 端口上 客户端的连接
            Console.WriteLine("服务器启动成功");

            Thread threadAccept = new Thread(accept);//创建一个接受客户端连接的线程   该线程机制可以接受多个客户端连接
            threadAccept.IsBackground = true;//后台执行
            threadAccept.Start();//启动线程
        }

        private void accept()
        {
            while(true)
            {
                //接受客户端连接,并返回socket, 该方法会阻塞挂起当前线程
                Socket client = serverSocket.Accept();
                IPEndPoint point = client.RemoteEndPoint as IPEndPoint; //远程连接过来IP 指客户端IP
                Console.WriteLine(point.Address + "[" + point.Port + "]" + "连接成功");

                clientList.Add(client);

                Thread thradReceive = new Thread(receive);//开启一个新线程用于接收数据
                thradReceive.IsBackground = true;
                thradReceive.Start(client);
            }
        }

        private void receive(Object obj)
        {
            while (true)
            {
                Socket client = obj as Socket;

                IPEndPoint point = client.RemoteEndPoint as IPEndPoint;

                try
                {
                    byte[] msg = new byte[1024];//申请一块字节数组用于存放接收的数据
                    int msgLen = client.Receive(msg);//接收字节数组  返回接收的长度     该函数会阻塞所在的线程 所以放到新线程中
                    string msgStr = point.Address + "[" + point.Port + "] : " + Encoding.UTF8.GetString(msg, 0, msgLen); //转换字节数组成字符串 并输出
                    Console.WriteLine(msgStr);
                    //client.Send(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(msg, 0, msgLen) + ", 楼上说得对"));
                    broadcast(client, msgStr);
                }
                catch
                {
                    Console.WriteLine(point.Address + "[" + point.Port + "]" + "积极断开");
                    clientList.Remove(client);
                    break;
                }
            }
        }

        private void broadcast(Socket clientOther, string msg)
        {
            foreach(var client in clientList)
            {
                if (client == clientOther)
                {
                    //当前消息是由client发来的, 不需要有任何响应
                }
                else
                {
                    client.Send(Encoding.UTF8.GetBytes(msg));
                }
            }
        }

    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ExampleNetServer
{
    class Program
    {
        static void Main(string[] args)
        {
            ServerControl server = new ServerControl();
            server.start();

            Console.ReadKey();
        }

    }
}

猜你喜欢

转载自blog.csdn.net/u012278016/article/details/90958251