asp.net基于C# Socket聊天程序(一个服务端,多个客户端)

部分代码:

命名空间:

 代码如下 复制代码

using System.Net; 
using System.Net.Sockets; 
using System.Threading; 
using System.IO; 

mainform.cs

 代码如下 复制代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace SyncChatServer
{
    public partial class MainForm : Form
    {
        /// <summary>
        /// 保存连接的所有用户
        /// </summary>
        private List<User> userList = new List<User>();

        /// <summary>
        /// 服务器IP地址
        /// </summary>;
        private string ServerIP;

        /// <summary>
        /// 监听端口
        /// </summary>
        private int port;
        private TcpListener myListener;

        /// <summary>
        /// 是否正常退出所有接收线程
        /// </summary>
        bool isNormalExit = false;

        public MainForm()
        {
            InitializeComponent();
            lst_State.HorizontalScrollbar = true;
            btn_Stop.Enabled = false;
            SetServerIPAndPort();
        }

        /// <summary>
        /// 根据当前程序目录的文本文件‘ServerIPAndPort.txt’内容来设定IP和端口
        /// 格式:127.0.0.1:8885
        /// </summary>
        private void SetServerIPAndPort()
        {
            FileStream fs = new FileStream("ServerIPAndPort.txt", FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            string IPAndPort = sr.ReadLine();
            ServerIP = IPAndPort.Split(':')[0]; //设定IP
            port = int.Parse(IPAndPort.Split(':')[1]); //设定端口
            sr.Close();
            fs.Close();
        }

        /// <summary>
        /// 开始监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Start_Click(object sender, EventArgs e)
        {
            myListener = new TcpListener(IPAddress.Parse(ServerIP), port);
            myListener.Start();
            AddItemToListBox(string.Format("开始在{0}:{1}监听客户连接", ServerIP, port));
            //创建一个线程监客户端连接请求
            Thread myThread = new Thread(ListenClientConnect);
            myThread.Start();
            btn_Start.Enabled = false;
            btn_Stop.Enabled = true;
        }

        /// <summary>
        /// 接收客户端连接
        /// </summary>
        private void ListenClientConnect()
        {
            TcpClient newClient = null;
            while (true)
            {
                try
                {
                    newClient = myListener.AcceptTcpClient();
                }
                catch
                {
                    //当单击‘停止监听’或者退出此窗体时 AcceptTcpClient() 会产生异常
                    //因此可以利用此异常退出循环
                    break;
                }
                //每接收一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息;
                User user = new User(newClient);
                Thread threadReceive = new Thread(ReceiveData);
                threadReceive.Start(user);
                userList.Add(user);
                AddItemToListBox(string.Format("[{0}]进入", newClient.Client.RemoteEndPoint));
                AddItemToListBox(string.Format("当前连接用户数:{0}", userList.Count));
            }

        }

        /// <summary>
        /// 处理接收的客户端信息
        /// </summary>
        /// <param name="userState">客户端信息</param>
        private void ReceiveData(object userState)
        {
            User user = (User)userState;
            TcpClient client = user.client;
            while (isNormalExit == false)
            {
                string receiveString = null;
                try
                {
                    //从网络流中读出字符串,此方法会自动判断字符串长度前缀
                    receiveString = user.br.ReadString();
                }
                catch (Exception)
                {
                    if (isNormalExit == false)
                    {
                        AddItemToListBox(string.Format("与[{0}]失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint));
                        RemoveUser(user);
                    }
                    break;
                }
                AddItemToListBox(string.Format("来自[{0}]:{1}",user.client.Client.RemoteEndPoint,receiveString));
                string[] splitString = receiveString.Split(',');
                switch(splitString[0])
                {
                    case "Login":
                        user.userName = splitString[1];
                        SendToAllClient(user,receiveString);
                        break;
                    case "Logout":
                        SendToAllClient(user,receiveString);
                        RemoveUser(user);
                        return;
                    case "Talk":
                        string talkString = receiveString.Substring(splitString[0].Length + splitString[1].Length + 2);
                        AddItemToListBox(string.Format("{0}对{1}说:{2}",user.userName,splitString[1],talkString));
                        SendToClient(user,"talk," + user.userName + "," + talkString);
                        foreach(User target in userList)
                        {
                            if(target.userName == splitString[1] && user.userName != splitString[1])
                            {
                                SendToClient(target,"talk," + user.userName + "," + talkString);
                                break;
                            }
                        }
                        break;
                    default:
                        AddItemToListBox("什么意思啊:" + receiveString);
                        break;
                }
            }
        }

        /// <summary>
        /// 发送消息给所有客户
        /// </summary>
        /// <param name="user">指定发给哪个用户</param>
        /// <param name="message">信息内容</param>
        private void SendToAllClient(User user, string message)
        {
            string command = message.Split(',')[0].ToLower();
            if (command == "login")
            {
                //获取所有客户端在线信息到当前登录用户
                for (int i = 0; i < userList.Count; i++)
                {
                    SendToClient(user, "login," + userList[i].userName);
                }
                //把自己上线,发送给所有客户端
                for (int i = 0; i < userList.Count; i++)
                {
                    if (user.userName != userList[i].userName)
                    {
                        SendToClient(userList[i], "login," + user.userName);
                    }
                }
            }
            else if(command == "logout")
            {
                for (int i = 0; i < userList.Count; i++)
                {
                    if (userList[i].userName != user.userName)
                    {
                        SendToClient(userList[i], message);
                    }
                }
            }
        }

        /// <summary>
        /// 发送 message 给 user
        /// </summary>
        /// <param name="user">指定发给哪个用户</param>
        /// <param name="message">信息内容</param>
        private void SendToClient(User user, string message)
        {
            try
            {
                //将字符串写入网络流,此方法会自动附加字符串长度前缀
                user.bw.Write(message);
                user.bw.Flush();
                AddItemToListBox(string.Format("向[{0}]发送:{1}", user.userName, message));
            }
            catch
            {
                AddItemToListBox(string.Format("向[{0}]发送信息失败",user.userName));
            }
        }

        /// <summary>
        /// 移除用户
        /// </summary>
        /// <param name="user">指定要移除的用户</param>
        private void RemoveUser(User user)
        {
            userList.Remove(user);
            user.Close();
            AddItemToListBox(string.Format("当前连接用户数:{0}",userList.Count));
        }

        private delegate void AddItemToListBoxDelegate(string str);
        /// <summary>
        /// 在ListBox中追加状态信息
        /// </summary>
        /// <param name="str">要追加的信息</param>
        private void AddItemToListBox(string str)
        {
            if (lst_State.InvokeRequired)
            {
                AddItemToListBoxDelegate d = AddItemToListBox;
                lst_State.Invoke(d, str);
            }
            else
            {
                lst_State.Items.Add(str);
                lst_State.SelectedIndex = lst_State.Items.Count - 1;
                lst_State.ClearSelected();
            }
        }

        /// <summary>
        /// 停止监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Stop_Click(object sender, EventArgs e)
        {
            AddItemToListBox("开始停止服务,并依次使用户退出!");
            isNormalExit = true;
            for (int i = userList.Count - 1; i >= 0; i--)
            {
                RemoveUser(userList[i]);
            }
            //通过停止监听让 myListener.AcceptTcpClient() 产生异常退出监听线程
            myListener.Stop();
            btn_Start.Enabled = true;
            btn_Stop.Enabled = false;
        }

        /// <summary>
        /// 关闭窗口时触发的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (myListener != null)
                btn_Stop.PerformClick();    //引发 btn_Stop 的Click事件
        }
    }
}

 

代码片段:

 代码如下 复制代码
/// <summary> 
/// 根据当前程序目录的文本文件‘ServerIPAndPort.txt’内容来设定IP和端口 
/// 格式:127.0.0.1:8885 
/// </summary>
private void SetServerIPAndPort() 

    FileStream fs = new FileStream("ServerIPAndPort.txt", FileMode.Open); 
    StreamReader sr = new StreamReader(fs); 
    string IPAndPort = sr.ReadLine(); 
    ServerIP = IPAndPort.Split(':')[0]; //设定IP 
    port = int.Parse(IPAndPort.Split(':')[1]); //设定端口 
    sr.Close(); 
    fs.Close(); 

 
 
/// <summary> 
/// 开始监听 
/// </summary> 
/// <param name="sender"></param> 
/// <param name="e"></param>
private void btn_Start_Click(object sender, EventArgs e) 

    myListener = new TcpListener(IPAddress.Parse(ServerIP), port); 
    myListener.Start(); 
    AddItemToListBox(string.Format("开始在{0}:{1}监听客户连接", ServerIP, port)); 
    //创建一个线程监客户端连接请求 
    Thread myThread = new Thread(ListenClientConnect); 
    myThread.Start(); 
    btn_Start.Enabled = false; 
    btn_Stop.Enabled = true; 

 
/// <summary> 
/// 接收客户端连接 
/// </summary>
private void ListenClientConnect() 

    TcpClient newClient = null; 
    while (true) 
    { 
        try 
        { 
            newClient = myListener.AcceptTcpClient(); 
        } 
        catch 
        { 
            //当单击‘停止监听’或者退出此窗体时 AcceptTcpClient() 会产生异常 
            //因此可以利用此异常退出循环 
            break; 
        } 
        //每接收一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息; 
        User user = new User(newClient); 
        Thread threadReceive = new Thread(ReceiveData); 
        threadReceive.Start(user); 
        userList.Add(user); 
        AddItemToListBox(string.Format("[{0}]进入", newClient.Client.RemoteEndPoint)); 
        AddItemToListBox(string.Format("当前连接用户数:{0}", userList.Count)); 
    } 
 

 
/// <summary> 
/// 处理接收的客户端信息 
/// </summary> 
/// <param name="userState">客户端信息</param>
private void ReceiveData(object userState) 

    User user = (User)userState; 
    TcpClient client = user.client; 
    while (isNormalExit == false) 
    { 
        string receiveString = null; 
        try 
        { 
            //从网络流中读出字符串,此方法会自动判断字符串长度前缀 
            receiveString = user.br.ReadString(); 
        } 
        catch (Exception) 
        { 
            if (isNormalExit == false) 
            { 
                AddItemToListBox(string.Format("与[{0}]失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint)); 
                RemoveUser(user); 
            } 
            break; 
        } 
        AddItemToListBox(string.Format("来自[{0}]:{1}",user.client.Client.RemoteEndPoint,receiveString)); 
        string[] splitString = receiveString.Split(','); 
        switch(splitString[0]) 
        { 
            case "Login": 
                user.userName = splitString[1]; 
                SendToAllClient(user,receiveString); 
                break; 
            case "Logout": 
                SendToAllClient(user,receiveString); 
                RemoveUser(user); 
                return; 
            case "Talk": 
                string talkString = receiveString.Substring(splitString[0].Length + splitString[1].Length + 2); 
                AddItemToListBox(string.Format("{0}对{1}说:{2}",user.userName,splitString[1],talkString)); 
                SendToClient(user,"talk," + user.userName + "," + talkString); 
                foreach(User target in userList) 
                { 
                    if(target.userName == splitString[1] && user.userName != splitString[1]) 
                    { 
                        SendToClient(target,"talk," + user.userName + "," + talkString); 
                        break; 
                    } 
                } 
                break; 
            default: 
                AddItemToListBox("什么意思啊:" + receiveString); 
                break; 
        } 
    } 

user.cs

 代码如下 复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace SyncChatServer
{
    class User
    {
        public TcpClient client { get; private set; }
        public BinaryReader br { get; private set; }
        public BinaryWriter bw { get; private set; }
        public string userName { get; set; }

        public User(TcpClient client)
        {
            this.client = client;
            NetworkStream networkStream = client.GetStream();
            br = new BinaryReader(networkStream);
            bw = new BinaryWriter(networkStream);
        }

        public void Close()
        {
            br.Close();
            bw.Close();
            client.Close();
        }

    }
}

 

program.cs

 代码如下 复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace SyncChatServer
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}

 

main.cs

 代码如下 复制代码

namespace SyncChatServer
{
    partial class MainForm
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.lst_State = new System.Windows.Forms.ListBox();
            this.btn_Start = new System.Windows.Forms.Button();
            this.btn_Stop = new System.Windows.Forms.Button();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            //
            // groupBox1
            //
            this.groupBox1.Controls.Add(this.lst_State);
            this.groupBox1.Location = new System.Drawing.Point(12, 12);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(523, 327);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "状态信息";
            //
            // lst_State
            //
            this.lst_State.Dock = System.Windows.Forms.DockStyle.Fill;
            this.lst_State.FormattingEnabled = true;
            this.lst_State.ItemHeight = 12;
            this.lst_State.Location = new System.Drawing.Point(3, 17);
            this.lst_State.Name = "lst_State";
            this.lst_State.Size = new System.Drawing.Size(517, 304);
            this.lst_State.TabIndex = 0;
            //
            // btn_Start
            //
            this.btn_Start.Location = new System.Drawing.Point(126, 346);
            this.btn_Start.Name = "btn_Start";
            this.btn_Start.Size = new System.Drawing.Size(75, 23);
            this.btn_Start.TabIndex = 1;
            this.btn_Start.Text = "开始监听";
            this.btn_Start.UseVisualStyleBackColor = true;
            this.btn_Start.Click += new System.EventHandler(this.btn_Start_Click);
            //
            // btn_Stop
            //
            this.btn_Stop.Location = new System.Drawing.Point(322, 346);
            this.btn_Stop.Name = "btn_Stop";
            this.btn_Stop.Size = new System.Drawing.Size(75, 23);
            this.btn_Stop.TabIndex = 2;
            this.btn_Stop.Text = "停止监听";
            this.btn_Stop.UseVisualStyleBackColor = true;
            this.btn_Stop.Click += new System.EventHandler(this.btn_Stop_Click);
            //
            // MainForm
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(547, 375);
            this.Controls.Add(this.btn_Stop);
            this.Controls.Add(this.btn_Start);
            this.Controls.Add(this.groupBox1);
            this.Name = "MainForm";
            this.Text = "SyncChatServer";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
            this.groupBox1.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.ListBox lst_State;
        private System.Windows.Forms.Button btn_Start;
        private System.Windows.Forms.Button btn_Stop;
    }
}

以上是不完整的代码片段,由于代码太多这里贴出来肯定眼花缭乱的。。

有需要的朋友还是下载源码看把

点击下载源文件

时间: 2024-10-01 19:27:23

asp.net基于C# Socket聊天程序(一个服务端,多个客户端)的相关文章

聊天室-关于java的聊天程序,分服务端和客户端,请java大神帮我调试一下,我检查没编写错误

问题描述 关于java的聊天程序,分服务端和客户端,请java大神帮我调试一下,我检查没编写错误 //服务端 package chatApp; import java.net.*; import java.io.*; import java.util.*; public class chatserverthree implements Runnable { public static final int PORT=1234; protected ServerSocket listen; stat

VB.net Socket 一个服务端多个客户端如何实现消息互通呢?

问题描述 各位兄弟朋友,小弟我在一个项目中急需Socket通信功能,我一直搞不定多个客户端的事情,麻烦大家帮帮忙嘛.最好是有源码!感激不尽!!问题描述:1:服务端一个2:客户端多个3:每个客户端可单独给服务端发信息,服务端也可给当前客户端回复信息4:服务端可以向所有的客户端发送信息,也可以单独给某个客户端发送信息5:语言vb.net 解决方案 解决方案二:自己先顶一下!解决方案三:http://bbs.csdn.net/topics/370172131http://blog.csdn.net/l

求大神指点 小弟想做一款小软件,一个服务端多个客户端,实现服务端能查看到客户端的IP、MAC、NAME、SystemName...并能远程控制客户端主机关机。

问题描述 详细解释下:1.服务端窗口界面显示信息:1).已连接的客户端(每个以一个按钮形式显示):2).光标放在客户端按钮上能显示出相应客户端的计算机名.IP地址.MAC地址.操作系统版本:3).点击客户端按钮能实现对客户端的主机远程关机.2.客户端实现的功能:开机自动运行该软件,并显示是否与服务器连接良好.本人目前只知道通信可以用SOCKET.获取计算机信息用management类,其他的对策不清楚,不知道对与不对,希望能得到大家的指点,说一下具体操作思路,解决方案,当然有案例就更好了,希望看

详解基于java的Socket聊天程序——客户端(附demo)_java

写在前面: 上周末抽点时间把自己写的一个简单Socket聊天程序的初始设计和服务端细化设计记录了一下,周二终于等来毕业前考的软考证书,然后接下来就是在加班的日子度过了,今天正好周五,打算把客户端的详细设计和Common模块记录一下,因为这个周末开始就要去忙其他东西了. 设计: 客户端设计主要分成两个部分,分别是socket通讯模块设计和UI相关设计. 客户端socket通讯设计: 这里的设计其实跟服务端的设计差不多,不同的是服务端是接收心跳包,而客户端是发送心跳包,由于客户端只与一个服务端进行通

c#网络编程-求c# socket聊天程序源码

问题描述 求c# socket聊天程序源码 我用c# winform自己写了一个局域网通信的软件,但是有点问题.求源码,类似QQ那样的,但我只要能实现在局域网聊天就行!! 解决方案 http://www.newxing.com/Code/CSharp/SOCKET_62.html 解决方案二: http://blog.csdn.net/liuwenqiangcs/article/details/7485950http://www.cnblogs.com/guoyiqi/archive/2011/

qt-使用QT,主机做了一个服务端,局域网中可以连接别人,别人连接自己输入字符就会断开连接

问题描述 使用QT,主机做了一个服务端,局域网中可以连接别人,别人连接自己输入字符就会断开连接 5C cmd下使用telnet也是输入字符就断开连接电脑杀毒软件一直没启动,防火墙全部关闭,端口号10000然后写了个客户端,同样的问题,输入字符断开连接.楼下依次上图 解决方案 解决方案二: 解决方案三: 解决方案四: 解决方案五: 输入字符a就出现了断开连接 下面上代码 解决方案六: chatsever.h #ifndef CHATSEVER_H#define CHATSEVER_H #inclu

winform-Winform客户端和Android客户端同时使用一个服务端,后端(C#)采用什么技术实现?

问题描述 Winform客户端和Android客户端同时使用一个服务端,后端(C#)采用什么技术实现? asp.net Webapi作为Android服务端(个人想法),Winform使用什么服务端呢?如果要求数据同步,使用观察者模式?使用的协议也是个问题.求大神指点! 解决方案 web API都可以,只要你 的服务器是什么平台就选对应的,比如windows就用C#等开发web API这样各种客户端都可以访问 解决方案二: 考虑到android调用的方便,建议直接用asp.net mvc返回js

java socket手机通信-关于java的问题:手机用socket连接电脑的服务端时老出现文件找不到的错误,求解决

问题描述 关于java的问题:手机用socket连接电脑的服务端时老出现文件找不到的错误,求解决 30C 解决方案 也可以私聊我.扣扣1944687725 解决方案二: 解决方案三: 你那个斜杠是不是写反了 passwdinput.dat 解决方案四: 你仔细看看出错的提示, 是读文件的时候找不到,对应的代码是在ServerThread.java的51行然后,你把路径改为绝对路径试一试,如果可以了,就是你相对路径的根目录不对.保证passwd文件夹在你的执行目录下 解决方案五: 右键 prope

基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询_javascript技巧

前言 基于SpringMVC+Bootstrap+DataTables实现数据表格服务端分页.模糊查询(非DataTables Search),页面异步刷新. 说明:sp:message标签是使用了SpringMVC国际化 效果 DataTable表格 关键字查询 自定义关键字查询,非DataTable Search 代码 HTML代码 查询条件代码 <!-- 查询.添加.批量删除.导出.刷新 --> <div class="row-fluid"> <di