C#实现服务器和客户端之间通信

TCP  套接字编程

服务器端实现步骤:

1、使用Socket类创建套接字。

2、利用Bind方法将创建的套接字绑定到指定的地址结构。

3、利用Listen方法设置套接字为监听模式,使得服务器进入被动打开状态。

4、接受客户端的连接请求。

5、接收、应答客户端的数据请求。

6、终止连接。

客户端实现步骤:

1、使用Socket类创建套接字。

2、调用Connect方法建立一个与TCP服务器的连接。

3、发送数据请求,接受服务器的数据应答。

4、终止连接。

一对一:

客户端代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
namespace Client
{
    class Problem
    {
        private static byte[] result = new byte[1024 * 1024];
        static Socket ClientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        static void Main(string[] args)
        {
            int Port = 8222;
            IPAddress IP = IPAddress.Parse("127.0.0.1");
            try
            {
                Console.WriteLine("连接服务器成功!!!");
                ClientSocket.Connect(new IPEndPoint(IP,Port));
            }
            catch(Exception ex)
            {
                Console.WriteLine("连接服务器失败,按回车键退出!");
                return;
            }
            for(int i=0;i<10;i++)
            {
                try
                {
                    Thread.Sleep(2000);
                    int ReceiveLength = ClientSocket.Receive(result);
                    Console.WriteLine("接收服务器消息:{0}",Encoding.ASCII.GetString(result,0,ReceiveLength));
                    Console.WriteLine("向服务器发送消息:");
                    string sb = Console.ReadLine();
                    string SendMessage = "向服务器发送消息:" + DateTime.Now + "\n" + sb;
                    ClientSocket.Send(Encoding.ASCII.GetBytes(SendMessage));
                }
                catch(Exception ex)
                {
                    ClientSocket.Shutdown(SocketShutdown.Both);
                    ClientSocket.Close();
                }
            }
            Console.WriteLine("消息发送完毕!!!");
            Console.WriteLine();
        }
    }
}
服务器代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
namespace Server
{
    class Program
    {
        public static void ListenClientConnect()
        {
            while(true)
            {
                Socket ClientSocket = ServerSocket.Accept();//send
                Console.WriteLine("向客户端发送消息:");
                string sb = Console.ReadLine();
                ClientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello:"+sb));
                Thread thread = new Thread(ReceiveMessage);
                thread.Start(ClientSocket);
            }
        }
        public static void ReceiveMessage(Object ClientSocket)
        {
            Socket MyClientSocket = (Socket)ClientSocket;
            while(true)
            {
                try
                {
                    int ReceiveNum = MyClientSocket.Receive(result);
                    Console.WriteLine("接受客户端{0}消息{1}:" ,MyClientSocket.RemoteEndPoint.ToString(),
                       Encoding.ASCII.GetString(result,0,ReceiveNum));
                    Console.WriteLine("向客户端发送消息:");
                    string sb = Console.ReadLine();
                    MyClientSocket.Send(Encoding.ASCII.GetBytes(sb));
                }
                catch(Exception ex)
                {
                    Console.WriteLine("404 Not found!!!");
                    MyClientSocket.Shutdown(SocketShutdown.Both);
                    MyClientSocket.Close();
                }
            }
        }
        private static byte[] result = new byte[1024 * 1024];
        static Socket ServerSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        static void Main(String[] args)
        {
            try
            {
                int Port = 8222;
                IPAddress IP = IPAddress.Parse("127.0.0.1");
                ServerSocket.Bind(new IPEndPoint(IP, Port));
                ServerSocket.Listen(10);
                Console.WriteLine("启动监听{0}成功",ServerSocket.LocalEndPoint.ToString());
                Thread thread = new Thread(ListenClientConnect);
                thread.Start();
                Thread.Sleep(2000);
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }
    }
}

一对多:

服务端代码:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Linq;
namespace Server
{
    class Program
    {
        public static void ListenConnection()
        {
            Socket ConnectionSocket = null;
            while(true)
            {
                try
                {
                    ConnectionSocket = ServerSocket.Accept();
                }
                catch(Exception ex)
                {
                    Console.WriteLine("监听套接字异常{0}",ex.Message);
                    break;
                }
                //获取客户端端口号和IP
                IPAddress ClientIP=(ConnectionSocket.RemoteEndPoint as IPEndPoint).Address;
                int ClientPort = (ConnectionSocket.RemoteEndPoint as IPEndPoint).Port;
                string SendMessage = "连接服务器成功\r\n" + "本地IP:" + ClientIP +
                    ",本地端口:" + ClientPort.ToString();
                //Console.WriteLine(SendMessage);
                ConnectionSocket.Send(Encoding.UTF8.GetBytes(SendMessage));
                string remotePoint = ConnectionSocket.RemoteEndPoint.ToString();
                Console.WriteLine("成功与客户端{0}建立连接!\t\n", remotePoint);
                ClientInformation.Add(remotePoint, ConnectionSocket);
                Thread thread = new Thread(ReceiveMessage);
                thread.IsBackground = true;
                thread.Start(ConnectionSocket);
            }
        }
        public static void ReceiveMessage(Object SocketClient)
        {
            Socket ReceiveSocket = (Socket)SocketClient;
            while(true)
            {
                byte[] result = new byte[1024 * 1024];
                try
                {
                    IPAddress ClientIP = (ReceiveSocket.RemoteEndPoint as IPEndPoint).Address;
                    int ClientPort = (ReceiveSocket.RemoteEndPoint as IPEndPoint).Port;
                    int ReceiveLength = ReceiveSocket.Receive(result);
                    string ReceiveMessage = Encoding.UTF8.GetString(result, 0, ReceiveLength);
                    Console.WriteLine("接收客户端:" + ReceiveSocket.RemoteEndPoint.ToString()+
                        "时间:"+DateTime.Now.ToString()+"\r\n"+"消息:"+ReceiveMessage+"\r\n\n");
                    foreach(string key in new List<string>(ClientInformation.Keys))
                    {
                        string s = ReceiveSocket.RemoteEndPoint.ToString();
                        if(key!=s)
                        {
                            Socket socket = ClientInformation[key];
                            Console.WriteLine("向客户端{0}发送消息:", key);
                            socket.Send(Encoding.UTF8.GetBytes(ReceiveMessage));
                        }
                    }
                    //Console.WriteLine("向客户端{0}发送消息:", ReceiveSocket.RemoteEndPoint.ToString());
                    //string sb = Console.ReadLine();
                    //ReceiveSocket.Send(Encoding.UTF8.GetBytes(sb));
                }
                catch(Exception ex)
                {
                    Console.WriteLine("监听出现异常!!!");
                    Console.WriteLine("客户端" + ReceiveSocket.RemoteEndPoint + "已经连接中断" + "\r\n" +
                        ex.Message + "\r\n" + ex.StackTrace + "\r\n");
                    foreach(string key in new List<string>(ClientInformation.Keys))
                    {
                        string s = ReceiveSocket.RemoteEndPoint.ToString();
                        if (key.Equals(s))
                        {
                            ClientInformation.Remove(key);
                        }
                    }
                    ReceiveSocket.Shutdown(SocketShutdown.Both);
                    ReceiveSocket.Close();
                    break;
                }
            }
        }
        //private static byte[] result = new byte[1024];
        //List<Socket> list = new List<Socket>();
        static Dictionary<string, Socket> ClientInformation = new Dictionary<string, Socket> { };
        static Socket ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        static void Main(String[] args)
        {
            try
            {
                int Port = 8333;
                IPAddress IP = IPAddress.Parse("127.0.0.1");
                ServerSocket.Bind(new IPEndPoint(IP, Port));
                ServerSocket.Listen(10);
                Console.WriteLine("启动监听成功!");
                Console.WriteLine("监听本地{0}成功", ServerSocket.LocalEndPoint.ToString());
                Thread ThreadListen = new Thread(ListenConnection);
                ThreadListen.IsBackground = true;
                ThreadListen.Start();
                Thread.Sleep(2000);
            }
            catch(Exception ex)
            {
                Console.WriteLine("监听异常!!!");
                ServerSocket.Shutdown(SocketShutdown.Both);
                ServerSocket.Close();
            }
            Console.ReadKey();
            Console.WriteLine("监听完毕,按任意键退出!");
        }
    }
}
客户端代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
namespace Client
{
    class Problem
    {
        private static byte[] result = new byte[1024 * 1024];
        static Socket ClientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        public static void ReceiveMessage()
        {
            while(true)
            {
                try
                {
                    int ReceiveLength = ClientSocket.Receive(result);
                    Console.WriteLine("接收服务器消息:{0}", Encoding.UTF8.GetString(result, 0, ReceiveLength));
                }
                catch(Exception ex)
                {
                    Console.WriteLine("出现异常了!!!");
                    Console.WriteLine(ex.Message);
                    ClientSocket.Shutdown(SocketShutdown.Both);
                    ClientSocket.Close();
                    break;
                }
            }
        }
        static void Main(string[] args)
        {
            int Port = 8333;
            IPAddress IP = IPAddress.Parse("127.0.0.1");
            try
            {
                ClientSocket.Connect(new IPEndPoint(IP,Port));
                Thread thread = new Thread(ReceiveMessage);
                thread.Start();
                Thread.Sleep(2000);
            }
            catch(Exception ex)
            {
                Console.WriteLine("连接服务器失败,按回车键退出!");
                return;
            }
            Console.WriteLine("连接服务器成功!!!");
            //int ReceiveLength = ClientSocket.Receive(result);
            //Console.WriteLine("接收服务器消息:{0}", Encoding.UTF8.GetString(result, 0, ReceiveLength));
            while (true)
            {
                try
                {
                    Thread.Sleep(2000);
                    Console.WriteLine("向服务器发送消息:");
                    string sb = Console.ReadLine();
                    string Client = ClientSocket.RemoteEndPoint.ToString();
                    string SendMessage = "接收客户端" + Client + "消息:" + DateTime.Now + "\n" + sb;
                    ClientSocket.Send(Encoding.ASCII.GetBytes(sb));
                }
                catch(Exception ex)
                {
                    ClientSocket.Shutdown(SocketShutdown.Both);
                    ClientSocket.Close();
                    break;
                }
            }
            Console.WriteLine("消息发送完毕!!!");
            Console.ReadLine();
        }
    }
}

下面是一对多的使用窗体界面显示的代码以及显示效果:

客户端代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
namespace ClientForm
{
    public partial class Form1 : Form
    {
        private byte[] result = new byte[1024 * 1024];
        private Socket ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        public Form1()
        {
            InitializeComponent();
            TextBox.CheckForIllegalCrossThreadCalls = false;
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            ;
        }
        private void textBox1_TextChanged(object sender, EventArgs e)//输入消息
        {
            //;
            string str = Console.ReadLine();
            textBox1.Text += str;
        }
        private void textBox2_TextChanged(object sender, EventArgs e)//ip
        {
            ;
        }
        private void textBox3_TextChanged(object sender, EventArgs e)//port
        {
            ;
        }
        private void button1_Click(object sender, EventArgs e)//发送消息
        {
            try
            {
                //Thread.Sleep(2000);
                richTextBox1.Text += "向服务器发送消息:\r\n";
                richTextBox1.Text += textBox1.Text + "\r\n";
                string sb = textBox1.Text;
                string Client = ClientSocket.RemoteEndPoint.ToString();
                string SendMessage = "接收客户端" + Client + "消息:" + DateTime.Now + "\r\n" + sb + "\r\n";
                ClientSocket.Send(Encoding.UTF8.GetBytes(sb));
                textBox1.Clear();
            }
            catch (Exception ex)
            {
                richTextBox1.Text += "服务器可能已经关闭!\r\n";
                ClientSocket.Shutdown(SocketShutdown.Both);
                ClientSocket.Close();
            }
        }
        private void button2_Click(object sender, EventArgs e)//连接服务器
        {
            int Port = Convert.ToInt32(textBox3.Text);
            IPAddress IP = IPAddress.Parse((string)textBox2.Text);
            try
            {
                ClientSocket.Connect(new IPEndPoint(IP, Port));
                richTextBox2.Text += "连接服务器成功!\r\n";
                Thread thread = new Thread(ReceiveMessage);
                thread.IsBackground = true;
                thread.Start();
            }
            catch (Exception ex)
            {
                richTextBox2.Text += "连接服务器失败!\r\n";
                return;
            }
        }
        private void label1_Click(object sender, EventArgs e)
        {
            ;
        }
        private void label2_Click(object sender, EventArgs e)
        {
            ;
        }
        private void richTextBox1_TextChanged(object sender, EventArgs e)//显示发送的消息
        {
            ;
        }
        private void richTextBox2_TextChanged(object sender, EventArgs e)//显示接收的消息
        {
            ;
        }
        private void ReceiveMessage()
        {
            while (true)
            {
                try
                {
                    int ReceiveLength = ClientSocket.Receive(result);
                    richTextBox2.Text += "接收服务器消息:\r\n";
                    string str = Encoding.UTF8.GetString(result, 0, ReceiveLength)+"\r\n";
                    richTextBox2.Text += str;
                }
                catch (Exception ex)
                {
                    richTextBox2.Text += "接收消息失败!\r\n";
                    ClientSocket.Shutdown(SocketShutdown.Both);
                    ClientSocket.Close();
                    break;
                }
            }
        }
    }
}

服务端代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using System.Threading;
namespace ServerForm
{
    public partial class Form1 : Form
    {
        private byte[] result = new byte[1024 * 1024];
        private Socket ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private Dictionary<string, Socket> ClientInformation = new Dictionary<string, Socket> { };
        public Form1()
        {
            InitializeComponent();
            TextBox.CheckForIllegalCrossThreadCalls = false;
            //在多线程程序中,新创建的线程不能访问UI线程创建的窗口控件
            //如果需要访问窗口控件则可以如此设置
        }
        private void label1_Click(object sender, EventArgs e)//ip
        {

        }
        private void label2_Click(object sender, EventArgs e)//Port
        {

        }
        private void label3_Click(object sender, EventArgs e)//在线列表
        {

        }
        private void richTextBox1_TextChanged(object sender, EventArgs e)//显示客户端之间/客户端消息
        {

        }
        private void richTextBox2_TextChanged(object sender, EventArgs e)//显示连接成功或者掉线的客户端
        {

        }
        private void richTextBox3_TextChanged(object sender, EventArgs e)//显示在线列表
        {

        }
        private void textBox1_TextChanged(object sender, EventArgs e)//IP
        {

        }
        
        private void textBox2_TextChanged(object sender, EventArgs e)//Port
        {

        }
        private void button1_Click(object sender, EventArgs e)//启动服务
        {
            try
            {
                int Port = Convert.ToInt32(textBox2.Text);
                IPAddress IP = IPAddress.Parse((string)textBox1.Text);
                ServerSocket.Bind(new IPEndPoint(IP, Port));
                ServerSocket.Listen(10);
                richTextBox2.Text += "启动监听成功!\r\n";
                richTextBox2.Text += "监听本地" + ServerSocket.LocalEndPoint.ToString() + "成功\r\n";
                Thread ThreadListen = new Thread(ListenConnection);
                ThreadListen.IsBackground = true;
                ThreadListen.Start();
                Thread.Sleep(2000);
            }
            catch(Exception ex)
            {
                richTextBox2.Text += "监听异常!!!\r\n";
                ServerSocket.Shutdown(SocketShutdown.Both);
                ServerSocket.Close();
            }
        }
        private void ListenConnection()
        {
            Socket ConnectionSocket = null;
            while (true)
            {
                try
                {
                    ConnectionSocket = ServerSocket.Accept();
                }
                catch (Exception ex)
                {
                    richTextBox2.Text += "监听套接字异常" + ex.Message;
                    //Console.WriteLine("监听套接字异常{0}", ex.Message);
                    break;
                }
                //获取客户端端口号和IP
                IPAddress ClientIP = (ConnectionSocket.RemoteEndPoint as IPEndPoint).Address;
                int ClientPort = (ConnectionSocket.RemoteEndPoint as IPEndPoint).Port;
                string SendMessage = "本地IP:" + ClientIP +
                    ",本地端口:" + ClientPort.ToString();
                ConnectionSocket.Send(Encoding.UTF8.GetBytes(SendMessage));
                string remotePoint = ConnectionSocket.RemoteEndPoint.ToString();
                richTextBox2.Text += "成功与客户端" + remotePoint + "建立连接\r\n";
                richTextBox3.Text += DateTime.Now+":"+remotePoint + "\r\n";
                ClientInformation.Add(remotePoint, ConnectionSocket);
                Thread thread = new Thread(ReceiveMessage);
                thread.IsBackground = true;
                thread.Start(ConnectionSocket);
            }
        }
        private void ReceiveMessage(Object SocketClient)
        {
            Socket ReceiveSocket = (Socket)SocketClient;
            while (true)
            {
                byte[] result = new byte[1024 * 1024];
                try
                {
                    IPAddress ClientIP = (ReceiveSocket.RemoteEndPoint as IPEndPoint).Address;
                    int ClientPort = (ReceiveSocket.RemoteEndPoint as IPEndPoint).Port;
                    int ReceiveLength = ReceiveSocket.Receive(result);
                    string str = ReceiveSocket.RemoteEndPoint.ToString();
                    string ReceiveMessage = Encoding.UTF8.GetString(result, 0, ReceiveLength);
                    richTextBox1.Text+= "接收客户端:" + ReceiveSocket.RemoteEndPoint.ToString() +
                    "时间:" + DateTime.Now.ToString() + "\r\n" + "消息:" + ReceiveMessage + "\r\n";
                    if (ClientInformation.Count == 1) continue;//只有一个客户端
                    List<string> test = new List<string>(ClientInformation.Keys);
                    for (int i = 0; i < ClientInformation.Count; i++)
                    {
                        Socket socket = ClientInformation[test[i]];
                        string s = ReceiveSocket.RemoteEndPoint.ToString();
                        if (test[i] != s)
                        {
                            richTextBox1.Text += DateTime.Now + "\r\n" + "客户端" + str + "向客户端" + test[i] + "发送消息:" + ReceiveMessage;
                            string ReceiveMessage1 = DateTime.Now + "\r\n" + "客户端" + str + "向您发送消息:" + ReceiveMessage;
                            socket.Send(Encoding.UTF8.GetBytes(ReceiveMessage1));
                        }
                    }
                }
                catch (Exception ex)
                {
                    richTextBox2.Text += "监听出现异常!\r\n";
                    richTextBox2.Text += "客户端" + ReceiveSocket.RemoteEndPoint + "已经连接中断" + "\r\n" +
                    ex.Message + "\r\n" + ex.StackTrace + "\r\n";
                    string s = ReceiveSocket.RemoteEndPoint.ToString();
                    ClientInformation.Remove(s);
                    ReceiveSocket.Shutdown(SocketShutdown.Both);
                    ReceiveSocket.Close();
                    break;
                }
            }
        }
    }
}
界面效果:

注:我这里在线列表显示的是所有连接过服务器的客户端,对于可能出现的乱码问题,将相应的ASCII改为UTF-8即可

新手我建议可以先看这两位博主的文章:

https://www.cnblogs.com/vaevvaev/p/6865968.html

https://www.cnblogs.com/yy3b2007com/p/7476458.html

客户端:


服务器:


猜你喜欢

转载自blog.csdn.net/dl962454/article/details/78990735