C#聊天程序服务端与客户端完整实例代码

 更新时间:2020年6月25日 11:36  点击:1908

本文所述为基于C#实现的多人聊天程序服务端与客户端完整代码。本实例省略了结构定义部分,服务端主要是逻辑处理部分代码,因此使用时需要完善一些窗体按钮之类的。

先看服务端代码如下:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace 多人聊天程序Server端
{
 /// <summary>
 /// 应用程序的主入口点。
 /// </summary>
 [STAThread]
 static void Main()
 {
  Application.Run(new Form1());
 }
 // 启动服务按钮
 private void button2_Click(object sender, System.EventArgs e)
 {
  try
  {
  // 必须填写端口
  if(txtPort.Text == "")
  {
   MessageBox.Show("请先填写服务端口号!", "提示");
   return;
  }
  Int32 port = Int32.Parse(txtPort.Text); // 获得端口号
  // 创建侦听的Socket
  mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  IPEndPoint localEP = new IPEndPoint(IPAddress.Any, port);
  // 将 Socket 绑定到本地的终结点上
  mainSocket.Bind(localEP);
  // 开始侦听,最大的连接数是 5
  mainSocket.Listen(5);
  // 开始一个异步操作接受客户的连接请求
  mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
  // 启动服务按钮不可用,停止服务按钮可用
  UpdateControls(true);
  }
  catch(SocketException se)
  {
  MessageBox.Show(se.Message, "提示");
  }
 }
 // 更新“启动服务按钮”和“停止服务”按钮的状态:是否可用;
 // 注意:两个按钮的状态是互斥的
 private void UpdateControls(bool onServe)
 {
  button2.Enabled = !onServe;
  button3.Enabled = onServe;
  if(onServe)
  {
  status.Text = "已启动服务";
  }
  else
  {
  status.Text = "未启动服务";
  }
 }
 // 回调函数,当客户连接上时,将会被调用
 public void OnClientConnect(IAsyncResult asyn)
 {
  try
  {
  // 调用EndAccept完成BeginAccept异步调用,返回一个新的Socket处理与客户的通信
  Socket workerSocket = mainSocket.EndAccept(asyn);
  // 增加客户数目
  Interlocked.Increment(ref clientNum);
  // 将 workerSocket Socket加入到 ArrayList 中
  workerSocketList.Add(workerSocket);
  // 发送欢迎信息给连接上服务器的客户
  string msg = "欢迎客户 " + clientNum + " 登录服务器\n";
  SendWelcomeToClient(msg, clientNum);
  // 在线客户数目改变,必须更新客户列表
  UpdateClientListControl();
  // 连接上的客户接收数据
  WaitForData(workerSocket, clientNum);
  // 主 Socket 返回,继续等待其它的连接请求
  mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
  }
  catch(ObjectDisposedException)
  {
  System.Diagnostics.Debugger.Log(0,"1","\n OnClientConnection: Socket已经关闭!\n");
  }
  catch(SocketException se)
  {
  MessageBox.Show(se.Message, "提示");
  }
 }
 // 发送欢迎信息给客户
 void SendWelcomeToClient(string msg, int clientNumber)
 {
  // 用UTF8格式来将string信息转化成byte数组形式
  byte[] byData = System.Text.Encoding.UTF8.GetBytes(msg);
  // 获得客户clientNumber对应的Socket
  Socket workerSocket = (Socket)workerSocketList[clientNumber - 1];
  // 将数据发给客户
  workerSocket.Send(byData);
 }
 // 该类保存当前的socket,它的客户号还有发送给服务器的数据
 public class SocketPacket
 {
  public System.Net.Sockets.Socket currentSocket; // 当前的Socket
  public int clientNumber; // 客户号
  public byte[] dataBuffer = new byte[1024]; // 发给服务器的数据
  // 构造函数
  public SocketPacket(System.Net.Sockets.Socket socket, int clientNumber)
  {
  currentSocket = socket;
  this.clientNumber = clientNumber;
  }
 }
 // 开始等待客户发送数据
 public void WaitForData(System.Net.Sockets.Socket socket, int clientNumber)
 {
  try
  {
  if(pfnWorkerCallBack == null)
  {
   // 当连接上的客户有写的操作的时候,调用回调函数
   pfnWorkerCallBack = new AsyncCallback(OnDataReceived);
  }
  SocketPacket socketPacket = new SocketPacket(socket, clientNumber);
  socket.BeginReceive(socketPacket.dataBuffer, 0, socketPacket.dataBuffer.Length,
            SocketFlags.None, pfnWorkerCallBack, socketPacket);
  }
  catch(SocketException se)
  {
  MessageBox.Show (se.Message, "提示");
  }
 }
 // 当客户写数据时,调用以下方法
 public void OnDataReceived(IAsyncResult asyn)
 {
  SocketPacket socketData = (SocketPacket)asyn.AsyncState ;
  try
  {
  // EndReceive完成BeginReceive异步调用,返回客户写入流的字节数
  int iRx = socketData.currentSocket.EndReceive(asyn);
  // 加 1 是因为字符串以 '\0' 作为结束标志符
  char[] chars = new char[iRx + 1];
  // 对客户发来的信息进行UTF8解码,存入chars字符数组中
  System.Text.Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();
  int charLen = decoder.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
  System.String szData = new System.String(chars);
  string msg = "客户 " + socketData.clientNumber + " 发的信息:" + szData;
  // 将客户发的数据加入到信息列表中
  AppendToRichEditControl(msg);
  // 等待数据
  WaitForData(socketData.currentSocket, socketData.clientNumber);
  }
  catch (ObjectDisposedException )
  {
  System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived: Socket已经关闭!\n");
  }
  catch(SocketException se)
  {
  if(se.ErrorCode == 10054)
  {
   // 将客户断开连接的信息写入信息列表中
   string msg = "客户 " + socketData.clientNumber + " 已断开了连接!" + "\n";
   AppendToRichEditControl(msg);
   // 移走已关闭的socket
   workerSocketList[socketData.clientNumber - 1] = null;
   // 更新客户列表
   UpdateClientListControl();
  }
  else
  {
   MessageBox.Show (se.Message, "提示");
  }
  }
 }
 // 更新信息列表,该方法可由主线程或其他工作线程所调用
 private void AppendToRichEditControl(string msg)
 {
  // 测试看是哪个线程调用了该方法
  if (InvokeRequired)
  {
  // We cannot update the GUI on this thread.
  // All GUI controls are to be updated by the main (GUI) thread.
  // Hence we will use the invoke method on the control which will
  // be called when the Main thread is free
  // Do UI update on UI thread
  object[] pList = {msg};
  txtRecvMsg.BeginInvoke(new UpdateRichEditCallback(OnUpdateRichEdit), pList);
  }
  else
  {
  // 创建该控件的主线程直接更新信息列表
  OnUpdateRichEdit(msg);
  }
 }
 // 添加信息到 txtRecvMsg 中
 private void OnUpdateRichEdit(string msg)
 {
 // txtRecvMsg.AppendText(msg);
  txtRecvMsg.Text = txtRecvMsg.Text + msg;
 }
 // 更新客户列表
 private void UpdateClientListControl()
 {
  if (InvokeRequired) // Is this called from a thread other than the one created
  // the control
  {
  clientList.BeginInvoke(new UpdateClientListCallback(UpdateClientList), null);
  }
  else
  {
  // 创建该控件的主线程直接更新信息列表
  UpdateClientList();
  }
 }
 // 更新客户列表
 void UpdateClientList()
 {
  clientList.Items.Clear(); // 清空客户列表
  for(int i = 0; i < workerSocketList.Count; i++)
  {
  // 加1,是因为数组从下标0开始,而我们的客户标号是从1开始
  string clientKey = Convert.ToString(i + 1);
  Socket workerSocket = (Socket)workerSocketList[i];
  if(workerSocket != null)
  {
   // 将连接着服务器的客户添加到客户列表中
   if(workerSocket.Connected)
   {
   clientList.Items.Add(clientKey);
   }
  }
  }
 }
 // 停止服务按钮
 private void button3_Click(object sender, System.EventArgs e)
 {
  CloseSockets();
  UpdateControls(false);
  // 更新客户列表
  UpdateClientListControl();
 }
 // 发送信息按钮
 private void button1_Click(object sender, System.EventArgs e)
 {
  // 如果在线客户列表不为空,则允许发送信息
  if (clientList.Items.Count != 0 )
  {
  try
  {
   string msg = txtSendMsg.Text;
   msg = "服务器信息: " + msg + "\n";
   byte[] byData = System.Text.Encoding.UTF8.GetBytes(msg);
   Socket workerSocket = null;
   for(int i = 0; i < workerSocketList.Count; i++)
   {
   workerSocket = (Socket)workerSocketList[i];
   if(workerSocket!= null)
   {
    // 发给所有连接上服务器的客户
    if(workerSocket.Connected)
    {
    workerSocket.Send(byData);
    }
   }
   }
  }
  catch(SocketException se)
  {
   MessageBox.Show(se.Message, "提示");
  }
  }
  else
  {
  MessageBox.Show("没有在线客户,不能发送信息!", "提示");
  }
 }
 // 清空信息按钮
 private void button4_Click(object sender, System.EventArgs e)
 {
  txtRecvMsg.Clear(); // 清空从客户发来的信息
 }
 // 关闭窗体按钮
 private void button5_Click(object sender, System.EventArgs e)
 {
  CloseSockets();
  Close();
 }
 // 关闭Socket
 void CloseSockets()
 {
  // 关闭主Socket
  if(mainSocket != null)
  {
  mainSocket.Close();
  }
  Socket workerSocket = null;
  // 关闭客户 Socket 数组
  for(int i = 0; i < workerSocketList.Count; i++)
  {
  workerSocket = (Socket)workerSocketList[i];
  if(workerSocket != null)
  {
   workerSocket.Close();
   workerSocket = null;
  }
  }
 }
 private void Form1_Load(object sender, System.EventArgs e)
 {
  try
  {
  // 获得本机的IP地址
  txtIP.Text = Dns.Resolve(Dns.GetHostName()).AddressList[0].ToString();
  // 启动时,启动服务按钮可用,停止服务按钮不可用
  UpdateControls(false);
  }
  catch(Exception exc)
  {
  MessageBox.Show(exc.Message, "提示");
  }
 }
 }
}

客户端主要实现接收来自服务端返回的消息、实现发送消息的操作界面,创建Socket实例,得到服务器的IP地址,更新控件,连接和断开等,具体代码如下:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
namespace 多人聊天程序Client端
{
 public class Form1 : System.Windows.Forms.Form
 {
 private System.Windows.Forms.Label label1;
 private System.Windows.Forms.TextBox txtIP;
 private System.Windows.Forms.Label label2;
 private System.Windows.Forms.Label label3;
 private System.Windows.Forms.RichTextBox txtSendMsg;
 private System.Windows.Forms.Label label4;
 private System.Windows.Forms.Button button1;
 private System.Windows.Forms.Button button2;
 private System.Windows.Forms.Button button3;
 private System.Windows.Forms.Button button4;
 private System.Windows.Forms.RichTextBox txtRecvMsg;
 private System.Windows.Forms.TextBox txtPort;
 private System.Windows.Forms.Button button5;
 private System.ComponentModel.Container components = null;
 byte[] m_dataBuffer = new byte[10];
 IAsyncResult result;
 public AsyncCallback pfnCallBack ;
 private System.Windows.Forms.Label status;
 private System.Windows.Forms.Label label5;
 public Socket clientSocket;
 public Form1()
 {
  InitializeComponent();
 }
 private void InitializeComponent()
 {
  this.label1 = new System.Windows.Forms.Label();
  this.txtIP = new System.Windows.Forms.TextBox();
  this.label2 = new System.Windows.Forms.Label();
  this.txtPort = new System.Windows.Forms.TextBox();
  this.label3 = new System.Windows.Forms.Label();
  this.txtSendMsg = new System.Windows.Forms.RichTextBox();
  this.label4 = new System.Windows.Forms.Label();
  this.status = new System.Windows.Forms.Label();
  this.txtRecvMsg = new System.Windows.Forms.RichTextBox();
  this.button1 = new System.Windows.Forms.Button();
  this.button2 = new System.Windows.Forms.Button();
  this.button3 = new System.Windows.Forms.Button();
  this.button4 = new System.Windows.Forms.Button();
  this.label5 = new System.Windows.Forms.Label();
  this.button5 = new System.Windows.Forms.Button();
  this.SuspendLayout();
  // label1
  this.label1.AutoSize = true;
  this.label1.Location = new System.Drawing.Point(16, 24);
  this.label1.Name = "label1";
  this.label1.Size = new System.Drawing.Size(60, 17);
  this.label1.TabIndex = 0;
  this.label1.Text = "服务器IP:";
  // txtIP
  this.txtIP.Location = new System.Drawing.Point(80, 24);
  this.txtIP.Name = "txtIP";
  this.txtIP.Size = new System.Drawing.Size(160, 21);
  this.txtIP.TabIndex = 1;
  this.txtIP.Text = "";
  // label2
  this.label2.AutoSize = true;
  this.label2.Location = new System.Drawing.Point(16, 56);
  this.label2.Name = "label2";
  this.label2.Size = new System.Drawing.Size(35, 17);
  this.label2.TabIndex = 2;
  this.label2.Text = "端口:";
  // txtPort
  this.txtPort.Location = new System.Drawing.Point(80, 56);
  this.txtPort.Name = "txtPort";
  this.txtPort.Size = new System.Drawing.Size(40, 21);
  this.txtPort.TabIndex = 3;
  this.txtPort.Text = "";
  // label3
  this.label3.AutoSize = true;
  this.label3.Location = new System.Drawing.Point(16, 96);
  this.label3.Name = "label3";
  this.label3.Size = new System.Drawing.Size(110, 17);
  this.label3.TabIndex = 4;
  this.label3.Text = "发送信息给服务器:";
  // txtSendMsg
  this.txtSendMsg.Location = new System.Drawing.Point(16, 120);
  this.txtSendMsg.Name = "txtSendMsg";
  this.txtSendMsg.Size = new System.Drawing.Size(224, 88);
  this.txtSendMsg.TabIndex = 5;
  this.txtSendMsg.Text = "";
  // label4
  this.label4.AutoSize = true;
  this.label4.Location = new System.Drawing.Point(16, 248);
  this.label4.Name = "label4";
  this.label4.Size = new System.Drawing.Size(60, 17);
  this.label4.TabIndex = 6;
  this.label4.Text = "连接状态:";
  // status
  this.status.Location = new System.Drawing.Point(80, 248);
  this.status.Name = "status";
  this.status.Size = new System.Drawing.Size(192, 23);
  this.status.TabIndex = 7;
  // txtRecvMsg
  this.txtRecvMsg.Location = new System.Drawing.Point(264, 80);
  this.txtRecvMsg.Name = "txtRecvMsg";
  this.txtRecvMsg.ReadOnly = true;
  this.txtRecvMsg.Size = new System.Drawing.Size(224, 144);
  this.txtRecvMsg.TabIndex = 8;
  this.txtRecvMsg.Text = "";
  // button1
  this.button1.Location = new System.Drawing.Point(280, 16);
  this.button1.Name = "button1";
  this.button1.Size = new System.Drawing.Size(88, 32);
  this.button1.TabIndex = 9;
  this.button1.Text = "连接";
  this.button1.Click += new System.EventHandler(this.button1_Click);
  // button2
  this.button2.Location = new System.Drawing.Point(384, 16);
  this.button2.Name = "button2";
  this.button2.Size = new System.Drawing.Size(88, 32);
  this.button2.TabIndex = 10;
  this.button2.Text = "断开";
  this.button2.Click += new System.EventHandler(this.button2_Click);
  // button3
  this.button3.Location = new System.Drawing.Point(280, 232);
  this.button3.Name = "button3";
  this.button3.Size = new System.Drawing.Size(88, 32);
  this.button3.TabIndex = 11;
  this.button3.Text = "清空信息";
  this.button3.Click += new System.EventHandler(this.button3_Click);
  // button4
  this.button4.Location = new System.Drawing.Point(384, 232);
  this.button4.Name = "button4";
  this.button4.Size = new System.Drawing.Size(88, 32);
  this.button4.TabIndex = 12;
  this.button4.Text = "关闭";
  this.button4.Click += new System.EventHandler(this.button4_Click);
  // label5
  this.label5.AutoSize = true;
  this.label5.Location = new System.Drawing.Point(264, 64);
  this.label5.Name = "label5";
  this.label5.Size = new System.Drawing.Size(134, 17);
  this.label5.TabIndex = 13;
  this.label5.Text = "收到服务器发来的信息:";
  // button5
  this.button5.Location = new System.Drawing.Point(16, 208);
  this.button5.Name = "button5";
  this.button5.Size = new System.Drawing.Size(224, 32);
  this.button5.TabIndex = 14;
  this.button5.Text = "发送信息";
  this.button5.Click += new System.EventHandler(this.button5_Click);
  // Form1
  this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
  this.ClientSize = new System.Drawing.Size(512, 277);
  this.Controls.Add(this.button5);
  this.Controls.Add(this.label5);
  this.Controls.Add(this.button4);
  this.Controls.Add(this.button3);
  this.Controls.Add(this.button2);
  this.Controls.Add(this.button1);
  this.Controls.Add(this.txtRecvMsg);
  this.Controls.Add(this.status);
  this.Controls.Add(this.label4);
  this.Controls.Add(this.txtSendMsg);
  this.Controls.Add(this.label3);
  this.Controls.Add(this.txtPort);
  this.Controls.Add(this.label2);
  this.Controls.Add(this.txtIP);
  this.Controls.Add(this.label1);
  this.Name = "Form1";
  this.Text = "多人聊天程序Client端";
  this.Load += new System.EventHandler(this.Form1_Load);
  this.ResumeLayout(false);
 }
 #endregion
 [STAThread]
 static void Main()
 {
  Application.Run(new Form1());
 }
 // 连接按钮
 private void button1_Click(object sender, System.EventArgs e)
 {
  // IP地址和端口号不能为空
  if(txtIP.Text == "" || txtPort.Text == "")
  {
  MessageBox.Show("请先完整填写服务器IP地址和端口号!", "提示");
  return;
  }
  try
  {
  // 创建Socket实例
  clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  // 得到服务器的IP地址
  IPAddress ipAddress = IPAddress.Parse(txtIP.Text);
  Int32 port = Int32.Parse(txtPort.Text);
  // 创建远程终结点
  IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
  // 连接到远程服务器
  clientSocket.Connect(remoteEP);
  if(clientSocket.Connected)
  {
   UpdateControls(true);
   WaitForData(); // 异步等待数据
  }
  }
  catch(SocketException se)
  {
  MessageBox.Show (se.Message, "提示");
  UpdateControls(false);
  }
 }
 // 等待数据
 public void WaitForData()
 {
  try
  {
  if(pfnCallBack == null)
  {
   // 当连接上的客户有写的操作的时候,调用回调函数
   pfnCallBack = new AsyncCallback(OnDataReceived);
  }
  SocketPacket socketPacket = new SocketPacket();
  socketPacket.thisSocket = clientSocket;
  result = clientSocket.BeginReceive(socketPacket.dataBuffer, 0, socketPacket.dataBuffer.Length,
   SocketFlags.None, pfnCallBack, socketPacket);
  }
  catch(SocketException se)
  {
  MessageBox.Show(se.Message, "提示");
  }
 }
 // 该类保存Socket以及发送给服务器的数据
 public class SocketPacket
 {
  public System.Net.Sockets.Socket thisSocket;
  public byte[] dataBuffer = new byte[1024]; // 发给服务器的数据
 }
 // 接收数据
 public void OnDataReceived(IAsyncResult asyn)
 {
  try
  {
  SocketPacket theSockId = (SocketPacket)asyn.AsyncState ;
  // EndReceive完成BeginReceive异步调用,返回服务器写入流的字节数
  int iRx = theSockId.thisSocket.EndReceive(asyn);
  // 加 1 是因为字符串以 '\0' 作为结束标志符
  char[] chars = new char[iRx + 1];
  // 用UTF8格式来将string信息转化成byte数组形式
  System.Text.Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();
  int charLen = decoder.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
  System.String szData = new System.String(chars);
  // 将收到的信息显示在信息列表中
  txtRecvMsg.Text = txtRecvMsg.Text + szData;
  // 等待数据
  WaitForData();
  }
  catch (ObjectDisposedException)
  {
  System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived: Socket已经关闭!\n");
  }
  catch(SocketException se)
  {
  if(se.ErrorCode == 10054)
  {
   string msg = "服务器" + "停止服务!" + "\n";
   txtRecvMsg.Text = txtRecvMsg.Text + msg;
   clientSocket.Close();
   clientSocket = null;
   UpdateControls(false);
  }
  else
  {
   MessageBox.Show(se.Message, "提示");
  }
  }
 }
 // 更新控件。连接和断开(发送信息)按钮的状态是互斥的
 private void UpdateControls(bool connected)
 {
  button1.Enabled = !connected;
  button2.Enabled = connected;
  button5.Enabled = connected;
  if(connected)
  {
  status.Text = "已连接";
  }
  else
  {
  status.Text = "无连接";
  }
 }
 // 断开按钮
 private void button2_Click(object sender, System.EventArgs e)
 {
  // 关闭Socket
  if(clientSocket != null)
  {
  clientSocket.Close();
  clientSocket = null;
  UpdateControls(false);
  }
 }
 // 发送信息按钮
 private void button5_Click(object sender, System.EventArgs e)
 {
  try
  {
  // 如果客户与服务器有连接,则允许发送信息
  if(clientSocket.Connected)
  {
   string msg = txtSendMsg.Text + "\n";
   // 用UTF8格式来将string信息转化成byte数组形式
   byte[] byData = System.Text.Encoding.UTF8.GetBytes(msg);
   if(clientSocket != null)
   {
   // 发送数据
   clientSocket.Send(byData);
   }
  }
  }
  catch(Exception se)
  {
  MessageBox.Show(se.Message, "提示");
  }
 }
 // 清空按钮
 private void button3_Click(object sender, System.EventArgs e)
 {
  txtRecvMsg.Clear(); // 清空信息列表
 }
 // 关闭按钮
 private void button4_Click(object sender, System.EventArgs e)
 {
  // 关闭Socket
  if(clientSocket != null)
  {
  clientSocket.Close();
  clientSocket = null;
  }
  Close(); // 关闭窗体
 }
 private void Form1_Load(object sender, System.EventArgs e)
 {
  UpdateControls(false); // 初始化时,只有连接按钮可用
 }
 }
}

[!--infotagslink--]

相关文章

  • C#实现简单的登录界面

    我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
  • 浅谈C# 字段和属性

    这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
  • C#中截取字符串的的基本方法详解

    这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
  • C#实现简单的Http请求实例

    这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
  • C#连接SQL数据库和查询数据功能的操作技巧

    本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
  • C#中new的几种用法详解

    本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
  • 使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)

    这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#开发Windows窗体应用程序的简单操作步骤

    这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • php语言实现redis的客户端

    php语言实现redis的客户端与服务端有一些区别了因为前面介绍过服务端了这里我们来介绍客户端吧,希望文章对各位有帮助。 为了更好的了解redis协议,我们用php来实现...2016-11-25
  • C#和JavaScript实现交互的方法

    最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • 轻松学习C#的基础入门

    轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
  • C#变量命名规则小结

    本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
  • C#绘制曲线图的方法

    这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • c#自带缓存使用方法 c#移除清理缓存

    这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
  • c#中(&&,||)与(&,|)的区别详解

    这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • 经典实例讲解C#递归算法

    这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25