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

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

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

Server端代码:

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端代码:

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端:

client端:

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

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

(0)

相关推荐

  • 详解C# Socket简单例子(服务器与客户端通信)

    这个例子只是简单实现了如何使用 Socket 类实现面向连接的通信. 注意:此例子的目的只是为了说明用套接字写程序的大概思路,而不是实际项目中的使用程序.在这个例子中,实际上还有很多问题没有解决,如消息边界问题.端口号是否被占用.消息命令的解析问题等.. 下面是两个程序的代码,(两个程序均为控制台程序) 先发服务端的(Server)完整代码如下: 引入命名空间: using System.Net.Sockets; using SystemNet; using SystemThreading; 完

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

    扩展: 由于server端是存储了所有server与client的连接对象,因此我们是可以基于此demo的基础上实现聊天系统: * 每当一个与用户发言时,是由server接收到的某个用户的发言信息的,此时服务器端可以通过循环发送该用户发送的信息给每个已经连接连接的用户(排除发送者). Server端代码: class Program { //创建一个和客户端通信的套接字 static Socket SocketWatch = null; //定义一个集合,存储客户端信息 static Dicti

  • Python socket网络编程TCP/IP服务器与客户端通信

    Python socket网络编程 初学 python,前段时间买了两本书<python 编程从入门到实践><Python 核心编程第三版>,第一本书主要讲的是一些基本语法和一些基本的使用方法,而第二本则深入很多,自己看来也是一知半解,刚好看到了这部分网络编程,依然有好多不太理解的地方,不过想来通过自己不断的摸索,不断地搜寻资料学习,早晚应该会变得通透吧....... 这部分主要使用的模块就是 socket 模块,在这个模块中可以找到 socket()函数,该函数用于创建套接字对象

  • python网络编程学习笔记(三):socket网络服务器

    1.TCP连接的建立方法 客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较. 步骤 TCP客户端 TCP服务器 第一步 建立socket对象  建立socket对象 第二步 调用connect()建立一个和服务器的连接 设置socket选项(可选) 第三步 无 绑定到一个端口(也可以是一个指定的网卡) 第四步 无 侦听连接 下面具体来讲这四步的建立方法: 第一步,建立socket对象:这里与客户端一样,依然是: s=socket.socket(socket.

  • Android编程之客户端通过socket与服务器通信的方法

    本文实例讲述了Android编程之客户端通过socket与服务器通信的方法.分享给大家供大家参考,具体如下: 下面是一个demo,Android客户端通过socket与服务器通信. 由于Android里面可以完全使用java.io.*包和java.net.*包,那么,实际上,逻辑部分与J2SE没有区别.只是UI代码不一样. Android客户端通过socket与服务器通信分为下面5步: (1)通过IP地址和端口实例化Socket,请求连接服务器: 复制代码 代码如下: socket = new

  • 详解Android 通过Socket 和服务器通讯(附demo)

    Android 通过Socket 和服务器通讯,是一种比较常用的通讯方式,时间比较紧,说下大致的思路,希望能帮到使用socket 进行通信的人 (1)开启一个线程发送消息    SocketOutputThread 消息是放在队列里的,当有消息后,进入队列,线程唤醒,发送消息,并反馈发送是否成功的回调 (2)开启一个线程接受服务器消息 SocketInputThread 为了防止一直收数据,浪费电池的电,采用NIO的方式读socket的数据,这个是本文的关键 (3)开启一个线程,做心跳,防止so

  • Java Socket编程服务器响应客户端实例代码

    通过输入流来读取客户端信息,相应的时候通过输出流来实现. 服务端类的代码: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; impo

  • nodejs socket实现的服务端和客户端功能示例

    本文实例讲述了nodejs socket实现的服务端和客户端功能.分享给大家供大家参考,具体如下: 使用node.js的net模块能很快的开发出基于TCP的服务端和客户端.直接贴代码. server.js /** * Created with JetBrains WebStorm. * User: Administrator * Date: 12-10-26 * Time: 下午3:44 * To change this template use File | Settings | File T

  • JAVA实现SOCKET多客户端通信的案例

    一.ServerSocket 1.为了方便调试,先创建一个界面用于显示客户端连接信息 基于javafx包写的一个简单界面! javafx.scene.control.TextArea ta = new javafx.scene.control.TextArea(); @Override public void start(Stage primaryStage) throws Exception { scene = new Scene(ta,450,200); primaryStage.setTi

  • 瑞星网络版24服务器,16000个客户端,无限升级

    瑞星网络版24服务器,16000个客户端,无限升级这个就不用多说了吧,看看那些网络版杀毒软件的恐怖价格....100个客户端就要几万几万的...http://download.rising.com.cn/for_down/netver/setup_me.exe中小企业版序列号: 24服务器,16736客户端 2RE9VM-WUC1QA-51MA0T-DR9108(其实就是这个序列号珍贵啊!)无限升级的地址:意思就是 :只要官方有升级包放出,同志们再点击下面这个地址,就可以下载到最新的升级包htt

  • node.js中express模块创建服务器和http模块客户端发请求

    首先下载express模块,命令行输入 npm install express 1.node.js中express模块创建服务端 在js代码同文件位置新建一个文件夹(www_root),里面存放网页文件等,就可以在浏览器中访问了 var express = require("express"); var path = require("path"); var app = express(); //目录 (当前目录下的www_root目录) app.use(expre

随机推荐