C#编写Socket服务器

打印 上一主题 下一主题

主题 980|帖子 980|积分 2942

1.Socket介绍

所谓套接字(Socket),就是对网络中差别主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的职位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口 



2.Socket一样平常应用模式(服务器端和客户端)



3.Socket的通讯过程





4.Socket通信基本流程图:


5.项目界面设计


6.实现焦点代码

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Net;
  11. using System.Net.Sockets;
  12. namespace TCPProgect
  13. {
  14.     public partial class FrmServer : Form
  15.     {
  16.         public FrmServer()
  17.         {
  18.             InitializeComponent();
  19.         }
  20.       
  21.         //第一步:调用socket()函数创建一个用于通信的套接字
  22.         private Socket listenSocket;
  23.         //字典集合:存储IP和Socket的集合
  24.         private Dictionary<string, Socket> OnLineList = new Dictionary<string, Socket>();
  25.         //当前时间
  26.         private string CurrentTime
  27.         {
  28.             get { return DateTime.Now.ToString("HH:mm:ss") + Environment.NewLine; }
  29.         }
  30.         //编码格式
  31.         Encoding econding = Encoding.Default;
  32.         private void btn_StartService_Click(object sender, EventArgs e)
  33.         {
  34.             //第一步:调用socket()函数创建一个用于通信的套接字
  35.             listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  36.             //第二步:给已经创建的套接字绑定一个端口号,这一般通过设置网络套接口地址和调用Bind()函数来实现
  37.             IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(this.txt_IP.Text.Trim()), int.Parse(this.txt_Port.Text.Trim()));
  38.             try
  39.             {
  40.                 listenSocket.Bind(endPoint);
  41.             }
  42.             catch (Exception ex)
  43.             {
  44.                 MessageBox.Show("服务器开启失败:" + ex.Message, "开启服务器");
  45.                 return;
  46.             }
  47.             //第三步:调用listen()函数使套接字成为一个监听套接字
  48.             listenSocket.Listen(10);
  49.             ShowMessage("服务器开启成功");
  50.             //开启一个线程监听
  51.             Task.Run(new Action(() =>
  52.                 {
  53.                     ListenConnection();
  54.                 }
  55.                 ));
  56.             this.btn_StartService.Enabled = false;
  57.         }
  58.         private void ListenConnection()
  59.         {
  60.             while (true)
  61.             {
  62.                 Socket clientSocket = listenSocket.Accept();
  63.                 string ip = clientSocket.RemoteEndPoint.ToString();
  64.                 //更新在线列表
  65.                 AddOnLine(ip, true);
  66.                 //更新在线列表集合
  67.                 OnLineList.Add(ip, clientSocket);
  68.                 ShowMessage(ip + "上线了");
  69.                 Task.Run(() => ReceiveMsg(clientSocket));
  70.             }
  71.         }
  72.         /// <summary>
  73.         /// 接收方法
  74.         /// </summary>
  75.         /// <param name="clientSocket"></param>
  76.         private void ReceiveMsg(Socket clientSocket)
  77.         {
  78.             while (true)
  79.             {
  80.                 //定义一个2M的缓冲区
  81.                 byte[] buffer = new byte[1024 * 1024 * 2];
  82.                 int length = -1;
  83.                 try
  84.                 {
  85.                     length = clientSocket.Receive(buffer);
  86.                 }
  87.                 catch (Exception)
  88.                 {
  89.                     //客户端下线了
  90.                     //更新在线列表
  91.                     string ip = clientSocket.RemoteEndPoint.ToString();
  92.                     AddOnLine(ip, false);
  93.                     OnLineList.Remove(ip);
  94.                     break;
  95.                 }
  96.                 if (length == 0)
  97.                 {
  98.                     //客户端下线了
  99.                     //更新在线列表
  100.                     string ip = clientSocket.RemoteEndPoint.ToString();
  101.                     AddOnLine(ip, false);
  102.                     OnLineList.Remove(ip);
  103.                     break;
  104.                 }
  105.                 if (length > 0)
  106.                 {
  107.                     string info = econding.GetString(buffer, 0, length);
  108.                     ShowMessage(info);
  109.                 }
  110.             }
  111.         }
  112.         /// <summary>
  113.         /// 在线列表更新
  114.         /// </summary>
  115.         /// <param name="clientIp"></param>
  116.         /// <param name="value"></param>
  117.         private void AddOnLine(string clientIp, bool value)
  118.         {
  119.             Invoke(new Action(() =>
  120.             {
  121.                 if (value)
  122.                 {
  123.                     this.lst_Online.Items.Add(clientIp);
  124.                 }
  125.                 else
  126.                 {
  127.                     this.lst_Online.Items.Remove(clientIp);
  128.                 }
  129.             }));
  130.         }
  131.         /// <summary>
  132.         /// 更新接收区
  133.         /// </summary>
  134.         /// <param name="info"></param>
  135.         private void ShowMessage(string info)
  136.         {
  137.             Invoke(new Action(() =>
  138.             {
  139.                 this.txt_Rcv.AppendText(CurrentTime + info + Environment.NewLine);
  140.             }));
  141.         }
  142.         /// <summary>
  143.         /// 消息发送
  144.         /// </summary>
  145.         /// <param name="sender"></param>
  146.         /// <param name="e"></param>
  147.         private void btn_Send_Click(object sender, EventArgs e)
  148.         {
  149.             if (this.lst_Online.SelectedItem != null)
  150.             {
  151.                 foreach (string item in this.lst_Online.SelectedItems)
  152.                 {
  153.                     if (OnLineList.ContainsKey(item))
  154.                     {
  155.                         OnLineList[item].Send(econding.GetBytes(this.txt_Send.Text.Trim()));
  156.                     }
  157.                 }
  158.             }
  159.             else
  160.             {
  161.                 MessageBox.Show("请先选择要发送的对象", "发送消息");
  162.             }
  163.         }
  164.         /// <summary>
  165.         /// 群发功能
  166.         /// </summary>
  167.         /// <param name="sender"></param>
  168.         /// <param name="e"></param>
  169.         private void btn_SendAll_Click(object sender, EventArgs e)
  170.         {
  171.             foreach (string item in this.lst_Online.Items)
  172.             {
  173.                 if (OnLineList.ContainsKey(item))
  174.                 {
  175.                     OnLineList[item].Send(econding.GetBytes(this.txt_Send.Text.Trim()));
  176.                 }
  177.             }
  178.         }
  179.     }
  180. }
复制代码
7.运行结果

        7.1 运行界面演示

         7.2 接收消息界面演示

         7.3 发送消息界面演示

         7.4 群发消息演示



源码地点:https://download.csdn.net/download/m0_73500215/89143273


如果你觉得我的分享有代价,那就请为我点赞收藏吧!你们的支持是我继续分享的动力。盼望大家可以或许积极批评,让我知道你们的想法和建议。谢谢!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用多少眼泪才能让你相信

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表