• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#聊天程序服务端与客户端完整实例代码

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

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c#ftp客户端源代码,c#socket客户端,c#获取客户端ip地址,c#客户端连接服务器,c#客户端和服务端等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文所述为基于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)
    {
    workerSocke



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C#开发教程之ftp操作方法整理
  • C#实现自定义FTP操作封装类实例
  • C#实现客户端弹出消息框封装类实例
  • C#聊天程序服务端与客户端完整实例代码
  • C#操作FTP出现500错误解决办法
  • c#操作ftp类分享
  • c#多线程网络聊天程序代码分享(服务器端和客户端)
  • 客户端实现蓝牙接收(C#)知识总结
  • C#版ftp方法实现类的代码

相关文章

  • 2017-05-28解析使用enumerator模式简化异步操作的详解
  • 2017-05-28c#自定义泛型类的实现
  • 2017-05-28C#使用伪随机数实现加密用户密码的方法
  • 2017-05-28C#一个简单的定时小程序实现代码
  • 2017-05-28C# DatagridView常用操作汇总
  • 2017-05-28C#进度轴控件分享
  • 2017-05-28c#保存窗口位置大小操作类(序列化和文件读写功能)
  • 2017-05-28C#波形图控件制作示例程序
  • 2017-05-28解析C#设计模式编程中的装饰者模式
  • 2017-05-28c# Winform 程序自动更新实现方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • c#日志记录帮助类分享
    • C# 泛型深入理解介绍
    • C# 未处理的“System.InvalidOperationException”类型的异常
    • 使用C#开发ActiveX控件
    • C#操作EXCEL DataTable转换的实例代码
    • C#检查Windows是否安装了某个服务的方法
    • C#实现同Active MQ通讯的方法
    • C#判断字符串是否是int/double(实例)
    • C#中使用反射遍历一个对象属性及值的小技巧
    • C#多线程编程详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有