服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)

C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)

2022-08-27 15:37风之_诉 C#

这篇文章主要介绍了C#使用Socket实现服务器与多个客户端通信(简单的聊天系统),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

扩展:
由于server端是存储了所有server与client的连接对象,因此我们是可以基于此demo的基础上实现聊天系统:

* 每当一个与用户发言时,是由server接收到的某个用户的发言信息的,此时服务器端可以通过循环发送该用户发送的信息给每个已经连接连接的用户(排除发送者)。

Server端代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
class Program
{
  //创建一个和客户端通信的套接字
  static Socket SocketWatch = null;
  //定义一个集合,存储客户端信息
  static Dictionary<string, Socket> ClientConnectionItems = new Dictionary<string, Socket> { };
 
  static void Main(string[] args)
  {
    //端口号(用来监听的)
    int port = 6000;
 
    //string host = "127.0.0.1";
    //IPAddress ip = IPAddress.Parse(host);
    IPAddress ip = IPAddress.Any;
 
    //将IP地址和端口号绑定到网络节点point上
    IPEndPoint ipe = new IPEndPoint(ip, port);
 
    //定义一个套接字用于监听客户端发来的消息,包含三个参数(IP4寻址协议,流式连接,Tcp协议)
    SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    //监听绑定的网络节点
    SocketWatch.Bind(ipe);
    //将套接字的监听队列长度限制为20
    SocketWatch.Listen(20);
 
 
    //负责监听客户端的线程:创建一个监听线程
    Thread threadwatch = new Thread(WatchConnecting);
    //将窗体线程设置为与后台同步,随着主线程结束而结束
    threadwatch.IsBackground = true;
    //启动线程  
    threadwatch.Start();
 
    Console.WriteLine("开启监听......");
    Console.WriteLine("点击输入任意数据回车退出程序......");
    Console.ReadKey();
 
    SocketWatch.Close();
 
    //Socket serverSocket = null;
 
    //int i=1;
    //while (true)
    //{
    //  //receive message
    //  serverSocket = SocketWatch.Accept();
    //  Console.WriteLine("连接已经建立!");
    //  string recStr = "";
    //  byte[] recByte = new byte[4096];
    //  int bytes = serverSocket.Receive(recByte, recByte.Length, 0);
    //  //recStr += Encoding.ASCII.GetString(recByte, 0, bytes);
    //  recStr += Encoding.GetEncoding("utf-8").GetString(recByte, 0, bytes);
 
    //  //send message
    //  Console.WriteLine(recStr);
 
    //  Console.Write("请输入内容:");
    //  string sendStr = Console.ReadLine();
 
    //  //byte[] sendByte = Encoding.ASCII.GetBytes(sendStr);
    //  byte[] sendByte = Encoding.GetEncoding("utf-8").GetBytes(sendStr);
 
    //  //Thread.Sleep(4000);
 
    //  serverSocket.Send(sendByte, sendByte.Length, 0);
    //  serverSocket.Close();
    //  if (i >= 100)
    //  {
    //    break;
    //  }
    //  i++;
    //}
      
    //sSocket.Close();
    //Console.WriteLine("连接关闭!");
 
 
    //Console.ReadLine();
  }
 
  //监听客户端发来的请求
  static void WatchConnecting()
  {
    Socket connection = null;
 
    //持续不断监听客户端发来的请求  
    while (true)
    {
      try
      {
        connection = SocketWatch.Accept();
      }
      catch (Exception ex)
      {
        //提示套接字监听异常  
        Console.WriteLine(ex.Message);
        break;
      }
 
      //客户端网络结点号
      string remoteEndPoint = connection.RemoteEndPoint.ToString();
      //添加客户端信息
      ClientConnectionItems.Add(remoteEndPoint, connection);
      //显示与客户端连接情况
      Console.WriteLine("\r\n[客户端\"" + remoteEndPoint + "\"建立连接成功! 客户端数量:" + ClientConnectionItems .Count+ "]");
 
      //获取客户端的IP和端口号
      IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
      int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port;
 
      //让客户显示"连接成功的"的信息
      string sendmsg = "[" + "本地IP:" + clientIP + " 本地端口:" + clientPort.ToString() + " 连接服务端成功!]";
      byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg);
      connection.Send(arrSendMsg);
 
      //创建一个通信线程  
      Thread thread = new Thread(recv);
      //设置为后台线程,随着主线程退出而退出
      thread.IsBackground = true;
      //启动线程  
      thread.Start(connection);
    }
  }
 
  /// <summary>
  /// 接收客户端发来的信息,客户端套接字对象
  /// </summary>
  /// <param name="socketclientpara"></param> 
  static void recv(object socketclientpara)
  {
    Socket socketServer = socketclientpara as Socket;
 
    while (true)
    {
      //创建一个内存缓冲区,其大小为1024*1024字节 即1M  
      byte[] arrServerRecMsg = new byte[1024 * 1024];
      //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度 
      try
      {
        int length = socketServer.Receive(arrServerRecMsg);
 
        //将机器接受到的字节数组转换为人可以读懂的字符串  
        string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
 
        //将发送的字符串信息附加到文本框txtMsg上  
        Console.WriteLine("\r\n[客户端:" + socketServer.RemoteEndPoint + " 时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")+ "]\r\n" + strSRecMsg);
 
        //Thread.Sleep(3000);
        //socketServer.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:"+strSRecMsg));
        //发送客户端数据
        if (ClientConnectionItems.Count > 0)
        {
          foreach (var socketTemp in ClientConnectionItems)
          {
            socketTemp.Value.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:" + strSRecMsg));
          }
        }
      }
      catch (Exception)
      {
        ClientConnectionItems.Remove(socketServer.RemoteEndPoint.ToString());
        //提示套接字监听异常
        Console.WriteLine("\r\n[客户端\"" + socketServer.RemoteEndPoint + "\"已经中断连接! 客户端数量:" + ClientConnectionItems.Count+"]");
        //关闭之前accept出来的和客户端进行通信的套接字
        socketServer.Close();
        break;
      }
    }
  }
}

Client端代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
class Program
{
  //创建1个客户端套接字和1个负责监听服务端请求的线程
  static Thread ThreadClient = null;
  static Socket SocketClient = null;
 
  static void Main(string[] args)
  {
    try
    {
      int port = 6000;
      string host = "127.0.0.1";//服务器端ip地址
 
      IPAddress ip = IPAddress.Parse(host);
      IPEndPoint ipe = new IPEndPoint(ip, port);
 
      //定义一个套接字监听
      SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
      try
      {
        //客户端套接字连接到网络节点上,用的是Connect
        SocketClient.Connect(ipe);
      }
      catch (Exception)
      {
        Console.WriteLine("连接失败!\r\n");
        Console.ReadLine();
        return;
      }
 
      ThreadClient = new Thread(Recv);
      ThreadClient.IsBackground = true;
      ThreadClient.Start();
 
      Thread.Sleep(1000);
      Console.WriteLine("请输入内容<按Enter键发送>:\r\n");
      while(true)
      {
        string sendStr = Console.ReadLine();
        ClientSendMsg(sendStr);
      }
 
      //int i = 1;
      //while (true)
      //{
      //  Console.Write("请输入内容:");
      //  string sendStr = Console.ReadLine();
 
      //  Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      //  clientSocket.Connect(ipe);
      //  //send message
      //  //byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr);
      //  byte[] sendBytes = Encoding.GetEncoding("utf-8").GetBytes(sendStr);
 
      //  //Thread.Sleep(4000);
 
      //  clientSocket.Send(sendBytes);
 
      //  //receive message
      //  string recStr = "";
      //  byte[] recBytes = new byte[4096];
      //  int bytes = clientSocket.Receive(recBytes, recBytes.Length, 0);
      //  //recStr += Encoding.ASCII.GetString(recBytes, 0, bytes);
      //  recStr += Encoding.GetEncoding("utf-8").GetString(recBytes, 0, bytes);
      //  Console.WriteLine(recStr);
 
      //  clientSocket.Close();
      //  if (i >= 100)
      //  {
      //    break;
      //  }
      //  i++;
      //}
        
      //Console.ReadLine();
      //return;
 
      //string result = String.Empty;
 
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.Message);
      Console.ReadLine();
    }
  }
 
  //接收服务端发来信息的方法 
  public static void Recv()
  {
      int x = 0;
    //持续监听服务端发来的消息
    while (true)
    {
      try
      {
        //定义一个1M的内存缓冲区,用于临时性存储接收到的消息
        byte[] arrRecvmsg = new byte[1024 * 1024];
 
        //将客户端套接字接收到的数据存入内存缓冲区,并获取长度
        int length = SocketClient.Receive(arrRecvmsg);
 
        //将套接字获取到的字符数组转换为人可以看懂的字符串
        string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
        if (x == 1)
        {
          Console.WriteLine("\r\n服务器:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "\r\n" + strRevMsg+"\r\n");
            
        }
        else
        {
          Console.WriteLine(strRevMsg + "\r\n");
          x = 1;
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine("远程服务器已经中断连接!" + ex.Message + "\r\n");
        break;
      }
    }
  }
 
  //发送字符信息到服务端的方法
  public static void ClientSendMsg(string sendMsg)
  {
    //将输入的内容字符串转换为机器可以识别的字节数组  
    byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
    //调用客户端套接字发送字节数组  
    SocketClient.Send(arrClientSendMsg);
  
}

测试结果:

server端:

C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)

client端:

C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)

C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)

C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)

代码下载地址:C-Socket.zip

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/luming666/article/details/79125453

延伸 · 阅读

精彩推荐
  • C#C#操作LINQ to SQL组件进行数据库建模的基本教程

    C#操作LINQ to SQL组件进行数据库建模的基本教程

    这篇文章主要介绍了C#操作LINQ to SQL组件进行数据库建模的基本教程,LINQ to SQL被集成在.NET框架之中,需要的朋友可以参考下...

    DebugLZQ9862021-11-15
  • C#C#环形缓冲区(队列)完全实现

    C#环形缓冲区(队列)完全实现

    这篇文章主要为大家详细介绍了C#环形缓冲区(队列)完全实现代码,感兴趣的小伙伴们可以参考一下...

    番茄炒西红柿12042021-12-02
  • C#c#消息提示框messagebox的详解及使用

    c#消息提示框messagebox的详解及使用

    这篇文章主要介绍了c#消息提示框messagebox的详解及使用的相关资料,需要的朋友可以参考下...

    yaoweijiao7432021-12-27
  • C#C#实现类型的比较示例详解

    C#实现类型的比较示例详解

    这篇文章主要给大家介绍了关于C#实现类型的比较的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的...

    solenovex6052022-07-21
  • C#Winform开发框架中如何使用DevExpress的内置图标资源

    Winform开发框架中如何使用DevExpress的内置图标资源

    这篇文章主要给大家介绍了关于在Winform开发框架中如何使用DevExpress的内置图标资源的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具...

    伍华聪4752022-03-06
  • C#轻松学习C#的正则表达式

    轻松学习C#的正则表达式

    轻松学习C#的正则表达式,对C#的正则表达式感兴趣的朋友可以参考本篇文章,帮助大家更灵活的运用C#的正则表达式。...

    丿木呈广予口贝5192021-11-03
  • C#利用C#编写Linux守护进程实例代码

    利用C#编写Linux守护进程实例代码

    如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件,下面这篇文章主要给大家介绍了关于利用C#编写Linux守护进程的相关...

    Chaunce7332022-02-19
  • C#关于C#中排序函数的总结

    关于C#中排序函数的总结

    下面小编就为大家带来一篇关于C#中排序函数的总结。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C#教程网11202021-11-22