返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >c#基于WinForm的Socket实现简单的聊天室 IM
  • 227
分享到

c#基于WinForm的Socket实现简单的聊天室 IM

2024-04-02 19:04:59 227人浏览 泡泡鱼
摘要

目录1:什么是Socket2:客服端和服务端的通信简单流程3:服务端Code:4:客服端Code:5:测试效果:6:完整Code GitHub下载路径 7:这个只是一个简单

1:什么是Socket

所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。

一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。

从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。

2:客服端和服务端的通信简单流程

3:服务端Code:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.windows.FORMs;

namespace ChartService
{
    using System.net;
    using System.Net.Sockets;
    using System.Threading;
    using ChatCommoms;
    using ChatModels;

    public partial class ServiceForm : Form
    {
        Socket _socket;
        private static List<ChatUserInfo> userinfo = new List<ChatUserInfo>();
        public ServiceForm()
        {
            InitializeComponent();

        }

        private void btnServicStart_Click(object sender, EventArgs e)
        {
            try
            {
                string ip = textBox_ip.Text.Trim();
                string port = textBox_port.Text.Trim();
                if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(port))
                {
                    MessageBox.Show("IP与端口不可以为空!");
                }
                ServiceStartAccept(ip, int.Parse(port));
            }
            catch (Exception)
            {
                MessageBox.Show("连接失败!或者ip,端口参数异常");
            }
        }
        public void ServiceStartAccept(string ip, int port)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.tcp);
            IPEndPoint endport = new IPEndPoint(IPAddress.Parse(ip), port);
            socket.Bind(endport);
            socket.Listen(10);
            Thread thread = new Thread(Recevice);
            thread.IsBackground = true;
            thread.Start(socket);
            textboMsg.AppendText("服务开启ok...");
        }

        /// <summary>
        /// 开启接听服务
        /// </summary>
        /// <param name="obj"></param>
        private void Recevice(object obj)
        {
            var socket = obj as Socket;
            while (true)
            {
                string remoteEpInfo = string.Empty;
                try
                {
                    Socket txSocket = socket.Accept();
                    _socket = txSocket;
                    if (txSocket.Connected)
                    {
                        remoteEpInfo = txSocket.RemoteEndPoint.ToString();
                        textboMsg.AppendText($"\r\n{remoteEpInfo}:连接上线了...");
                        var clientUser = new ChatUserInfo
                        {
                            UserID = Guid.NewGuid().ToString(),
                            ChatUid = remoteEpInfo,
                            ChatSocket = txSocket
                        };
                        userinfo.Add(clientUser);


                        listBoxCoustomerList.Items.Add(new ChatUserInfoBase { UserID = clientUser.UserID, ChatUid = clientUser.ChatUid });
                        listBoxCoustomerList.DisplayMember = "ChatUid";
                        listBoxCoustomerList.ValueMember = "UserID";

                        ReceseMsgGoing(txSocket, remoteEpInfo);
                    }
                    else
                    {
                        if (userinfo.Count > 0)
                        {
                            userinfo.Remove(userinfo.Where(c => c.ChatUid == remoteEpInfo).FirstOrDefault());
                            //移除下拉框对于的socket或者叫用户
                        }
                        break;
                    }
                }
                catch (Exception)
                {
                    if (userinfo.Count > 0)
                    {
                        userinfo.Remove(userinfo.Where(c => c.ChatUid == remoteEpInfo).FirstOrDefault());
                        //移除下拉框对于的socket或者叫用户
                    }
                }
            }

        }

        /// <summary>
        /// 接受来自客服端发来的消息
        /// </summary>
        /// <param name="txSocket"></param>
        /// <param name="remoteEpInfo"></param>
        private void ReceseMsgGoing(Socket txSocket, string remoteEpInfo)
        {

            //退到一个客服端的时候 int getlength = txSocket.Receive(recesiveByte); 有抛异常
            Thread thread = new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        byte[] recesiveByte = new byte[1024 * 1024 * 4];
                        int getlength = txSocket.Receive(recesiveByte);
                        if (getlength <= 0) { break; }

                        var getType = recesiveByte[0].ToString();
                        string getmsg = Encoding.UTF8.GetString(recesiveByte, 1, getlength - 1);
                        ShowMsg(remoteEpInfo, getType, getmsg);
                    }
                    catch (Exception)
                    {
                        //string userid = userinfo.FirstOrDefault(c => c.ChatUid == remoteEpInfo)?.ChatUid;
                        listBoxCoustomerList.Items.Remove(remoteEpInfo);
                        userinfo.Remove(userinfo.FirstOrDefault(c => c.ChatUid == remoteEpInfo));//从集合中移除断开的socket

                        listBoxCoustomerList.DataSource = userinfo;//重新绑定下来的信息
                        listBoxCoustomerList.DisplayMember = "ChatUid";
                        listBoxCoustomerList.ValueMember = "UserID";
                        txSocket.Dispose();
                        txSocket.Close();
                    }
                }
            });
            thread.IsBackground = true;
            thread.Start();

        }

        private void ShowMsg(string remoteEpInfo, string getType, string getmsg)
        {
            textboMsg.AppendText($"\r\n{remoteEpInfo}:消息类型:{getType}:{getmsg}");
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;
            this.textBox_ip.Text = "192.168.1.101";//初始值
            this.textBox_port.Text = "50000";
        }

        /// <summary>
        /// 服务器发送消息,可以先选择要发送的一个用户
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            var getmSg = textBoxSendMsg.Text.Trim();
            if (string.IsNullOrWhiteSpace(getmSg))
            {
                MessageBox.Show("要发送的消息不可以为空", "注意"); return;
            }
            var obj = listBoxCoustomerList.SelectedItem;
            int getindex = listBoxCoustomerList.SelectedIndex;
            if (obj == null || getindex == -1)
            {
                MessageBox.Show("请先选择左侧用户的用户"); return;
            }
            var getChoseUser = obj as ChatUserInfoBase;
            var sendMsg = ServiceSockertHelper.GetSendMsgByte(getmSg, ChatTypeInfoEnum.StringEnum);
            userinfo.FirstOrDefault(c => c.ChatUid == getChoseUser.ChatUid)?.ChatSocket?.Send(sendMsg);
        }

        /// <summary>
        /// 给所有登录的用户发送消息,群发了
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            var getmSg = textBoxSendMsg.Text.Trim();
            if (string.IsNullOrWhiteSpace(getmSg))
            {
                MessageBox.Show("要发送的消息不可以为空", "注意"); return;
            }
            if (userinfo.Count <= 0)
            {
                MessageBox.Show("暂时没有客服端登录!"); return;
            }
            var sendMsg = ServiceSockertHelper.GetSendMsgByte(getmSg, ChatTypeInfoEnum.StringEnum);
            foreach (var usersocket in userinfo)
            {
                usersocket.ChatSocket?.Send(sendMsg);
            }
        }

        /// <summary>
        /// 服务器给发送震动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendSnak_Click(object sender, EventArgs e)
        {
            var obj = listBoxCoustomerList.SelectedItem;
            int getindex = listBoxCoustomerList.SelectedIndex;
            if (obj == null || getindex == -1)
            {
                MessageBox.Show("请先选择左侧用户的用户"); return;
            }
            var getChoseUser = obj as ChatUserInfoBase;

            byte[] sendMsgByte = ServiceSockertHelper.GetSendMsgByte("", ChatTypeInfoEnum.Snake);
            userinfo.FirstOrDefault(c => c.ChatUid == getChoseUser.ChatUid)?.ChatSocket.Send(sendMsgByte);
        }


    }
}

4:客服端Code:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ChatClient
{
    using ChatCommoms;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;
            this.textBoxIp.Text = "192.168.1.101";//先初始化一个默认的ip等
            this.textBoxPort.Text = "50000";
        }

        Socket clientSocket;
        /// <summary>
        /// 客服端连接到服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnServicStart_Click(object sender, EventArgs e)
        {
            try
            {
                var ipstr = textBoxIp.Text.Trim();
                var portstr = textBoxPort.Text.Trim();
                if (string.IsNullOrWhiteSpace(ipstr) || string.IsNullOrWhiteSpace(portstr))
                {
                    MessageBox.Show("要连接的服务器ip和端口都不可以为空!");
                    return;
                }
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(IPAddress.Parse(ipstr), int.Parse(portstr));
                labelStatus.Text = "连接到服务器成功...!";
                ReseviceMsg(clientSocket);

            }
            catch (Exception)
            {
                MessageBox.Show("请检查要连接的服务器的参数");
            }
        }
        private void ReseviceMsg(Socket clientSocket)
        {

            Thread thread = new Thread(() =>
             {
                 while (true)
                 {
                     try
                     {
                         Byte[] byteContainer = new Byte[1024 * 1024 * 4];
                         int getlength = clientSocket.Receive(byteContainer);
                         if (getlength <= 0)
                         {
                             break;
                         }
                         var getType = byteContainer[0].ToString();
                         string getmsg = Encoding.UTF8.GetString(byteContainer, 1, getlength - 1);

                         GetMsgFomServer(getType, getmsg);
                     }
                     catch (Exception ex)
                     {
                     }
                 }
             });
            thread.IsBackground = true;
            thread.Start();

        }

        private void GetMsgFomServer(string strType, string msg)
        {
            this.textboMsg.AppendText($"\r\n类型:{strType};{msg}");
        }

        /// <summary>
        /// 文字消息的发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            var msg = textBoxSendMsg.Text.Trim();
            var sendMsg = ServiceSockertHelper.GetSendMsgByte(msg, ChatModels.ChatTypeInfoEnum.StringEnum);
            int sendMsgLength = clientSocket.Send(sendMsg);
        }
    }
}

5:测试效果:

6:完整Code gitHUb下载路径 

https://github.com/zrf518/winformSocketChat.git

7:这个只是一个简单的聊天练习Demo,待进一步完善(实现部分功能,传递的消息byte[0]为消息的类型,用来判断是文字,还是图片等等),欢迎大家指教

以上就是C#基于WinForm的Socket实现简单的聊天室 IM的详细内容,更多关于c# WinForm实现聊天室 IM的资料请关注编程网其它相关文章!

--结束END--

本文标题: c#基于WinForm的Socket实现简单的聊天室 IM

本文链接: https://lsjlt.com/news/125154.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • c#基于WinForm的Socket实现简单的聊天室 IM
    目录1:什么是Socket2:客服端和服务端的通信简单流程3:服务端Code:4:客服端Code:5:测试效果:6:完整Code GitHUb下载路径 7:这个只是一个简单...
    99+
    2024-04-02
  • C#基于Socket实现简单聊天室功能
    因为这段时间在学习Socket,所以就试着写了一个简单的聊天室。主要分为服务器端和多个客户端。利用服务器端作数据中转站,实现消息群发。 1、服务器端有两个类: using Syste...
    99+
    2024-04-02
  • C++基于socket UDP网络编程实现简单聊天室功能
    本文实例为大家分享了C++基于socket UDP实现简单聊天室功能的具体代码,供大家参考,具体内容如下 0.通信步骤流程图 (左:服务器;右:客户端;) 1.服务器代码 1.1服...
    99+
    2024-04-02
  • Android 基于Socket的聊天室实例
    Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路。一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行...
    99+
    2022-06-06
    聊天室 socket Android
  • C++基于socket编程实现聊天室功能
    本文实例为大家分享了C++基于socket编程实现聊天室的具体代码,供大家参考,具体内容如下 服务端 // server.cpp : 此文件包含 "main" 函数。程序执行将在...
    99+
    2024-04-02
  • C#基于Socket的TCP通信实现聊天室案例
    本文实例为大家分享了C#基于Socket的TCP通信实现聊天室的具体代码,供大家参考,具体内容如下 一、Socket(套接字)通信概念 套接字(socket)是通信的基石,用于描述I...
    99+
    2024-04-02
  • 基于websocket实现简单聊天室对话
    本文实例为大家分享了websocket实现简单聊天室对话的具体代码,供大家参考,具体内容如下 首先搭建一个node的环境,在app.js中写入以下代码 npm install s...
    99+
    2024-04-02
  • Java基于Socket实现多人聊天室
    本文实例为大家分享了Java基于Socket实现简易版多人聊天室的具体代码,供大家参考,具体内容如下 一、 聊天室需求 1、一个服务端,多个客户端;2、实现客户端和服务端的交互;3、...
    99+
    2024-04-02
  • C++基于socket多线程实现网络聊天室
    本文实例为大家分享了C++基于socket多线程实现网络聊天室的具体代码,供大家参考,具体内容如下 1. 实现图解 2. 聊天室服务端:TCP_Server_Chat.cpp ...
    99+
    2024-04-02
  • Android基于socket实现的简单C/S聊天通信功能
    本文实例讲述了Android基于socket实现的简单C/S聊天通信功能。分享给大家供大家参考,具体如下: 主要想法:在客户端上发送一条信息,在后台开辟一个线程充当服务端,收到...
    99+
    2022-06-06
    通信 socket Android
  • Java Socket实现简易聊天室
    Java-Socket编程实现简易聊天室(TCP),供大家参考,具体内容如下 实现一个服务器接收多个客户端 测试: 首先启动服务器,然后启动三个客户端,输入三个不同的用户名,分别在聊...
    99+
    2024-04-02
  • 如何使用C#基于Socket的TCP通信实现聊天室
    这篇文章给大家分享的是有关如何使用C#基于Socket的TCP通信实现聊天室的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体内容如下一.Socket(套接字)通信概念套接字(socket)是通信的基石,用于描述...
    99+
    2023-06-29
  • Java通过Socket实现简单多人聊天室
    本文实例为大家分享了Java通过Socket实现多人聊天室的具体代码,供大家参考,具体内容如下 Socket可以实现网络上两个程序通过双向通道进行数据的交换,此外它是Java中网络T...
    99+
    2024-04-02
  • Android中基于XMPP协议实现IM聊天程序与多人聊天室
    简单的IM聊天程序 由于项目需要做一个基于XMPP协议的Android通讯软件。故开始研究XMPP。 XMPP协议采用的是客户端-服务器架构,所有从一个客户端发到另一个客户端的...
    99+
    2022-06-06
    xmpp 程序 聊天室 Android
  • C语言实现简单的聊天室功能
    用C语言实现简单的聊天室功能,供大家参考,具体内容如下 服务器端 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> ...
    99+
    2024-04-02
  • 基于C++实现TCP聊天室功能
    本文实例为大家分享了C++实现TCP聊天室功能的具体代码,供大家参考,具体内容如下 TCPServer.cpp: // TCPServer.cpp : Defines the ...
    99+
    2024-04-02
  • C#基于WebSocket实现聊天室功能
    本文实例为大家分享了C#基于WebSocket实现聊天室功能的具体代码,供大家参考,具体内容如下 前面两篇温习了,C# Socket内容 本章根据Socket异步聊天室修改成WebS...
    99+
    2024-04-02
  • 基于Pythonsocket实现简易网络聊天室
    目录1.socket_ui.py 服务端1-1. 依赖引用1-2. 实现过程1-3. 实现效果2.client_ui.py 客户端2-1. 依赖引用2-2. 实现过程2-3. 实现效...
    99+
    2024-04-02
  • node+socket实现简易聊天室功能
    本文实例为大家分享了node+socket实现简易聊天室的具体代码,供大家参考,具体内容如下 服务端 const net = require('net') const serv...
    99+
    2024-04-02
  • Java Socket怎样实现简易聊天室
    这篇文章主要介绍了Java Socket怎样实现简易聊天室,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Java-Socket编程实现简易聊天室(TCP),具体内容如下实现一...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作