您的位置:首页 > 其它

Winform应用-简单的C/S聊天程序

2015-11-04 22:36 337 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/Mudi674880855/article/details/49645365

Winform应用-简单的C/S聊天程序

服务器端代码块

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

namespace ChatServer
{
public partial class FrmServer : Form
{
//声明一个用来通信的Socket
Socket socketSend;
//声明一个用来存储客户端IP和端口号的集合
Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();

public FrmServer()
{
InitializeComponent();
}

/// <summary>
/// 开始监听 按钮的点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
//当点击开始监听的时候,创建一个用来监听Ip地址和端口号的Socket
Socket socketListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//设置IP对象(侦听所有网络接口上的客户端活动)
IPAddress ip = IPAddress.Any;
//创建端口号对象
IPEndPoint port = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
//将端口号对象与套接字相关联
socketListener.Bind(port);
//向文本框中输出提示信息
ShowMsg("监听成功");
//将Socket设置为侦听状态,挂起连接队列的最大长度为10
socketListener.Listen(10);

//创建一个新的线程来执行Listen方法
Thread th = new Thread(Listen);
//将该线程设置为后台线程
th.IsBackground = true;
//将该线程设置为可执行状态,等待CPU处理并传入Listen方法所需的参数
th.Start(socketListener);
}

/// <summary>
/// 等待客户端连接,并且创建一个用来通信的Socket
/// </summary>
/// <param name="o">button1_Click()方法传过来的用来监听的Socket</param>
void Listen(object o)
{
//将传入的参数转换为Socket类型
Socket socketListener = o as Socket;
//等待客户端连接,并且创建一个用来通信的Socket
while (true)
{
//等待客户端连接
socketSend = socketListener.Accept();
//若有客户端连接,将客户端信息添加到dicSocket集合中
dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
//向下拉框中添加数据
cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());
//调用ShowMsg方法将字符串输出到文本框中
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");
//开启一个新线程,不停的接收客户端发来的消息
Thread th = new Thread(Receive);
//将该线程设置为后台线程
th.IsBackground = true;
//将该线程设置为可执行状态,等待CPU处理并传入Receive方法所需的参数
th.Start(socketSend);
}
}

/// <summary>
/// 服务器端不停的接收客户端发来的消息
/// </summary>
/// <param name="o">Listen()方法传过来的用来通信数据的Socket</param>
void Receive(object o)
{
//将传入的参数转换为Socket类型
Socket socketSend = o as Socket;
while (true)
{
//客户端连接成功后,服务器端应该接受客户端发来的消息
byte[] buffer = new byte[1024 * 1024 * 2];
//实际接收到的有效数据字节数
int r = socketSend.Receive(buffer);
//当接收到的有效数据为0时,跳出该循环
if (r == 0)
{
break;
}
//将byte[]数组中的数据转换成为字符串
string str = Encoding.UTF8.GetString(buffer, 0, r);
//调用ShowMsg方法将字符串输出到文本框中
ShowMsg(socketSend.RemoteEndPoint + ":" + str);
}
}

/// <summary>
/// 用来显示消息的方法
/// </summary>
/// <param name="str"></param>
void ShowMsg(string str)
{
//向文本框中追加字符串并换行
txtLog.AppendText(str + "\r\n");
}

/// <summary>
/// 点击 发送消息 按钮的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
//获得文本框中输入的字符串
string str = txtMsg.Text;
//将获得的字符串转换成为byte[]数组
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
//声明一个泛型集合(用来在原来byte[]的第一位加上一个标记位)
List<byte> list = new List<byte>();
//向集合的第一个元素中添加标记符0
list.Add(0);
//将buffer添加到list中
list.AddRange(buffer);
//将list转换成为新的byte[]数组
byte[] newBuffer = list.ToArray();
//获得下拉框中选中的IP地址和端口号
string ip = cboUsers.SelectedItem.ToString();
//通过Socket将newBuffer发送给指定的客户端
dicSocket[ip].Send(newBuffer);
//将文本框中的字符串清空
txtMsg.Text = "";
}

/// <summary>
/// 点击 发送文件 按钮的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSendFile_Click(object sender, EventArgs e)
{
//从文本框中获得要发送的文件的全路径
string path = txtPath.Text;
//创建一个文件流来传输数据
using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read))
{
//声明一个大小为5MB的字节数组
byte[] buffer = new byte[1024 * 1024 * 5];
//将文件读取到文件流中
int r = fsRead.Read(buffer, 0, buffer.Length);
//声明一个list泛型集合(用来在原来byte[]的第一位加上一个标记位)
List<byte> list = new List<byte>();
//向list的第一个元素添加标记符1
list.Add(1);
//将byte[]添加到list中
list.AddRange(buffer);
//将list集合重新转换为新的byte[]数组
byte[] newBuffer = list.ToArray();
//通过Socket将newBuffer发送给指定的客户端
dicSocket[cboUsers.SelectedItem.ToString()].Send(newBuffer, 0, r + 1, SocketFlags.None);
}
}

/// <summary>
/// 点击 选择 按钮的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnChoice_Click(object sender, EventArgs e)
{
//创建一个打开文件对话框
OpenFileDialog ofd = new OpenFileDialog();
//设置对话框的标题
ofd.Title = "请选择要发送的文件";
//设置文件名筛选器
ofd.Filter = "所有文件|*.*";
//打开对话框
ofd.ShowDialog();
//将选择文件的全路径赋值给文本框
txtPath.Text = ofd.FileName;
}

/// <summary>
/// 点击 震动 按钮的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btndoudong_Click(object sender, EventArgs e)
{
//声明一个byte[]数组来存储标记符
byte[] buffer = new byte[1];
//赋值
buffer[0] = 2;
//通过Socket将buffer发送给指定的客户端
dicSocket[cboUsers.SelectedItem.ToString()].Send(buffer);
}

/// <summary>
/// 载入窗体时执行的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FrmServer_Load(object sender, EventArgs e)
{
//关闭跨线程调用的异常捕获
Control.CheckForIllegalCrossThreadCalls = false;
}
}
}

客户端代码块

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

namespace ChatClient
{
public partial class frmClient : Form
{
//声明一个用来通信的Socket
Socket socketSend;
public frmClient()
{
InitializeComponent();
}

/// <summary>
/// 点击 连接 按钮的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnLink_Click(object sender, EventArgs e)
{
//创建负责通信的Socket
socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//将文本框中的IP地址字符串转换为IP地址对象
IPAddress ip = IPAddress.Parse(txtIP.Text);
//创建端口号对象
IPEndPoint port = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
//连接服务器端
socketSend.Connect(port);
//调用ShowMsg方法在文本框中显示提示信息
ShowMsg("连接成功");
//创建一个新线程来执行Receive方法
Thread th = new Thread(Receive);
//将线程设置为后台线程
th.IsBackground = true;
//将线程设置为克执行状态,等待CPU调用
th.Start();
}

/// <summary>
/// 在文本框中显示字符串的方法
/// </summary>
/// <param name="str"></param>
void ShowMsg(string str)
{
//在文本框中追加字符串并换行
txtLog.AppendText(str + "\r\n");
}

/// <summary>
/// 点击 发送消息 按钮的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
//获得文本框中输入的字符串
string str = txtMsg.Text;
//将字符串转换成为byte[]数组
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
//通过Socket将数据发送给服务器端
socketSend.Send(buffer);
//清空文本框中的内容
txtMsg.Text = "";
}

/// <summary>
/// 不停的接收服务器端发送来的数据的方法
/// </summary>
void Receive()
{
while (true)
{
//声明一个2MB的字节数组
byte[] buffer = new byte[1024 * 1024 * 2];
//实际接收到的有效数据字节数
int r = socketSend.Receive(buffer);
//当接收到的有效数据为0时,跳出该循环
if (r == 0)
{
break;
}
//如果数据数组中第一个元素为0,表示发送的数据为文本数据
if (buffer[0] == 0)
{
//将数据转换为字符串
string str = Encoding.UTF8.GetString(buffer, 1, r - 1);
//调用ShowMsg方法将字符串输出到文本框中
ShowMsg(socketSend.RemoteEndPoint + ":" + str);
}
//如果数据数组中第一个元素为1,表示发送的数据为文件数据
else if (buffer[0] == 1)
{
//创建一个保存对话框
SaveFileDialog sfd = new SaveFileDialog();
//设置标题
sfd.Title = "请选择您要保存的文件";
//设置文件名筛选器
sfd.Filter = "所有文件|*.*";
//打开对话框
sfd.ShowDialog(this);
//获得保存的位置的全路径
string path = sfd.FileName;
//通过文件流将数据写入到指定位置
using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
fsWrite.Write(buffer, 1, r - 1);
}
//提示保存成功
MessageBox.Show("保存成功");
}
//如果数据数组中第一个元素为2,表示发送的数据为让客户端窗体抖动
else if (buffer[0] == 2)
{
//调用抖动的方法
ZhenDong();
}
}
}

/// <summary>
/// 让客户端窗体抖动的方法
/// </summary>
void ZhenDong()
{
for (int i = 0; i < 500; i++)
{
this.Location = new Point(200,200);
this.Location = new Point(202,202);
}
}

/// <summary>
/// 载入窗体时执行的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmClient_Load(object sender, EventArgs e)
{
//关闭跨线程调用的异常捕获
Control.CheckForIllegalCrossThreadCalls = false;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: