c#实现多线程局域网聊天系统

   这篇文章主要介绍了c#实现多线程局域网聊天系统的相关代码,有此方面需求的小伙伴可以参考下。

  觉得好有点帮助就顶一下啦。

  socke编程,支持多客户端,多线程操作避免界面卡死。

  开启socket

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

private void button1_Click(object sender, EventArgs e)
{
try
{
int port = int.Parse(txt_port.Text);
string host = txt_ip.Text;
//创建终结点
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
//创建Socket并开始监听
newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建一个Socket对象,如果用UDP协议,则要用SocketTyype.Dgram类型的套接字
newsock.Bind(ipe); //绑定EndPoint对象
newsock.Listen(0); //开始监听
//为新建立的连接创建新的Socket
acceptClientThread = new Thread(new ThreadStart(AcceptClient));
acceptClientThread.Start();
SetText("开始监听");
}
catch (Exception exp)
{
CommonFunction.WriteLog(exp, exp.Message);
}
}

  监控端口,接收客户端

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

/// <summary>
/// 接受客户端,可接受多个客户端同时连入,并对连入的客户端注册到客户端列表
/// </summary>
public void AcceptClient()
{
try
{
while (true)
{
Socket client = newsock.Accept();
ip = client.Handle;
RegeistUser(client.Handle, client);
Thread clientThread = new Thread(new ParameterizedThreadStart(ReceiveData));
object o = client;
clientThread.Start(o);
}
}
catch (Exception exp)
{
CommonFunction.WriteLog(exp, exp.Message);
}
}

  接收客户端数据并广播数据

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

/// <summary>
/// 接收客户端数据并,转发到目标客户端。
/// </summary>
public void ReceiveData(object o)
{
try
{
while (true)
{
Socket client = (Socket)o;
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
bytes = client.Receive(recvBytes, recvBytes.Length, 0); //从客户端接受消息
recvStr = Encoding.UTF8.GetString(recvBytes, 0, bytes);
SendMessage(client, recvStr);
SetText(recvStr);
CommonFunction.WriteErrorLog(recvStr);
}
}
catch (Exception exp)
{
CommonFunction.WriteLog(exp, exp.Message);
}
}

  判断是用户注册还是发送消息

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

/// <summary>
/// 判断是用户注册还是发送消息
/// </summary>
/// <param name="p_strMessage"></param>
public void SendMessage(Socket client,string p_strMessage)
{
if (p_strMessage.StartsWith("@"))
{
RegeistUser(p_strMessage, client);
}
else if (p_strMessage.StartsWith(">"))
{
 
DeleteClident(p_strMessage);
}
else
{
//SendMessageToTarget(p_strMessage);
SendAllMessage(p_strMessage);
}
}

  将socket注册为指定用户名

  ?

1
2
3
4
5
6
7
8
9
10
11
12

/// <summary>
/// 将socket注册为指定用户名
/// </summary>
/// <param name="user"></param>
/// <param name="ss"></param>
public void RegeistUser(string user, Socket ss)
{
user = user.Remove(0, 1);
userSocketDict.Add(user, ss);
SendOneMessage(ss, "欢迎" + user + "连入!");
RefreshClient();
}

  从客户端字典中移除客户端

  ?

1
2
3
4
5
6
7
8
9
10

/// <summary>
/// 从客户端字典中移除客户端
/// </summary>
/// <param name="p_strMessage"></param>
public void DeleteClident(string p_strMessage)
{
p_strMessage = p_strMessage.Remove(0, 1);
userSocketDict.Remove(p_strMessage);
RefreshClient();
}

  群发消息

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13

/// <summary>
/// 群发消息
/// </summary>
/// <param name="p_strsend"></param>
public void SendAllMessage(string p_strsend)
{
//MessageBox.Show(p_strsend);
foreach (string item in userSocketDict.Keys)
{
byte[] bs = Encoding.UTF8.GetBytes(p_strsend);
userSocketDict[item].Send(bs, bs.Length, 0);
}
}

  给文本框赋值

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

public delegate void SetTextHandler(string text);
/// <summary>
/// 给文本框赋值
/// </summary>
/// <param name="text"></param>
private void SetText(string text)
{
if (rich_back.InvokeRequired == true)
{
SetTextHandler set = new SetTextHandler(SetText);//委托的方法参数应和SetText一致
rich_back.Invoke(set, new object[] { text }); //此方法第二参数用于传入方法,代替形参text
}
else
{
rich_back.Text += "n" + text;
}
 
}

  连入服务器

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

private void button1_Click(object sender, EventArgs e)
{
try
{
user = txt_name.Text;
int port = int.Parse(txt_port.Text);
string host = txt_ip.Text;
//创建终结点EndPoint
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port); //把ip和端口转化为IPEndPoint的实例
//创建Socket并连接到服务器
Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 创建Socket
cc = c;
c.Connect(ipe); //连接到服务器
clientThread = new Thread(new ThreadStart(ReceiveData));
clientThread.Start();
//向服务器发送本机用户名,以便服务器注册客户端
SendMessage("@" + txt_name.Text);
}
catch (ArgumentException ex)
{
Console.WriteLine("argumentNullException:{0}", ex);
}
catch (SocketException exp)
{
Console.WriteLine("SocketException:{0}",exp);
}
}

  向服务器发送消息

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13

private void button3_Click(object sender, EventArgs e)
{
if (""==txt_target.Text)
{
MessageBox.Show("未选择对话人物");
return;
}
//向服务器发送信息
string sendStr = txt_name.Text + "@" + target + ":" + txt_message.Text;
SendMessage(sendStr);
rch_back.Text += "n" + sendStr;
txt_message.Text = "";
}

  隐身

  ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14

private void button2_Click(object sender, EventArgs e)
{
try
{
SendMessage(">" + txt_name.Text);
//cc.Disconnect(true);
//cc.Shutdown(SocketShutdown.Both);
//cc.Close();
}
catch (Exception exp)
{
CommonFunction.WriteLog(exp, exp.Message);
}
}

  以上所述就是本文的全部内容了,希望大家能够喜欢。

时间: 2024-08-29 11:00:55

c#实现多线程局域网聊天系统的相关文章

求大神指点迷津

问题描述 大致情况:2014届的本科毕业生,本来应该去年9月份就该找程序员的工作,但是因为个人和家庭原因,一直在当地县城电脑城打工,今年春节过后才去大城市找程序员的工作(自己之前没有软件公司实习经验),从那以后待了3家单位...1.在一家做应用软件开发的小公司只待了1个多星期就被辞退(老大给的理由是我心态太急躁,过于急于求成...)我开始确实从基础工作干起,但是感觉他们对技术方面很保守,我问什么他们很少理睬,这个我也觉得工作确实应该靠自己,但是好多技术方面的文档资料我都接触不到,没法研究,最后连

急!!Java具备以下能力能力在北京能找到月薪的工作!!

问题描述 技能1.熟悉Java面向对象编程2.能熟练运用JSP.Servlet.JavaBean技术进行Web编程,能熟练使用Ajax3.能熟练使用Struts,Spring,Hibernate等框架进行编程:4.熟悉面向对象分析和设计OOA/D,熟悉UML5.熟悉mysql,sqlserver,熟悉Jboss.weblogic6.熟悉J2EE规范,熟悉:EJB3.0,了解web2.0,了解redhatlinux7.理解MVC.DAO.DTO.Singleton.Factory.Observer

真巧, 我刚好做了一个扫描整个网段的多线程程序, 不过利用ping加参数

程序|多线程 扫描500个IP10秒钟左右, 一个IP等待0.3秒说来惭愧, 我觉得是用java写的过程编程, 少贴一点仅供参考:package steeven; import java.sql.*;import java.io.*;import java.util.*;import java.text.*;import javax.servlet.http.*; public class Ip extends Common implements Runnable{   public Strin

c# 获得局域网主机列表实例

using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;using System.Net;using System.Threading; namespace WindowLanSearch{ /// <summary> /// Form1 的摘要说明. /// </summary&g

使用Control.Invoke处理多线程应用程序界面

程序|多线程 使用Control.Invoke处理多线程应用程序界面 使用单一线程,在进行大计算量或耗时的操作时,会使界面失去响应.Control.Invoke 提供了一个在工作线程中更新见面的简单办法.该函数会把作为参数的回调函数提交给应用程序的界面进程(一般是主线程)的队列中,等待处理.这样,对界面的操作便无须担心同步.互锁等问题. 以下例子摘自一个局域网资源搜索程序        可以看到,线程池中的工作线程通过调用TreeView的Invoke方法,并提供一个回调函数,来实现对TreeV

局域网聊天软件(winsocket)

程序实现功能: 局域网聊天软件,启动即可找到在线设备,并能够进行简单的文字聊天. 其实下面这个框图已经说明了程序的绝大部分功能原理. 核心类的程序框图 我觉得,这个程序中使用的最好的技术,应该就是IOCP了.后面我会针对IOCP好好地写一篇博文,这个技术虽然刚学的时候有点乱,但是确实很好用. 上面的框图中中间的UDPServer线程等待的事件完成是MainServer线程在Listen函数调用结束后设置的事件.这里忘了标了. 说明 前几天在实验室看<Windows网络与通信程序设计>这本书,看

局域网共享上网技巧四则

问题1:办公室中有五台计算机,是通过共享ADSL宽带方式接入到Internet的,在这些计算机中上网时 ,发现有的网页无法打开:可是通过拨号或专线上网时,发现这些网页都是可以打开的,不知道为什么会 出现这种现象? 解答:出现这种现象,很有可能是ADSL宽带上网时,所用到的PPPoE协议"惹"的祸.由于 PPPoE协议对每次发送或接受的数据包容量有一定的限制,一旦超过这个限制(最大传输单元只能为1500 ),可能导致网络访问不正常.为了避免发送或接受的数据包容量太大,你必须对TCP数据包

修改设置 提高Vista中多线程下载速度

在Windows Vista中,微软为TCP/IP引入了名为"Auto Tuning"的新特性,从理论上说,"Auto Tuning"能够根据网络应用情况调整.优化,从而提高网络传输速率.在Windows Vista的默认设置中,"Auto Tuning"是自动启用的. 不过,在实际应用中,"Auto Tuning"有时候并不能起到预期中的效果,尤其在网卡使用第三方驱动时,甚至会大大降低网络连接速率.根据系统的具体情况,由&q

基于select I/O模型的远程目录浏览与多线程文件下载

摘要: 服务器端基于select I/O模型.为防止程序界面阻塞, 有一个子线程用于不断接收socket并select其中的处理.客户端只有一个线程函数, 不过其利用率很高, 可用于远程目录交换, 请求文件大小, 创建若干线程来下载文件.文件传输有上传和下载,还有对等传输, 这个项目中, 传输文件具体指下载. 正文: 一 数据及数据结构 1 传送包, 客户端主线程给子线程传递的结构体 typedef struct{ char packetType; // 请求类型 r:request rootd