---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
服务端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.IO;
namespace MyChatroomServer
{
public partial class MyChatroomServer : Form
{
public MyChatroomServer()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false; //关闭对文本框的跨线程操作
}
Thread threadWatch = null;//负责监听客户端连接请求的线程
Socket SocketWatch = null;//负责监听的套接字
Socket sokConnectin = null;//负责通信的套接字
Thread threadRec = null;
Socket sokRec = null;
//保存服务器端所有负责和客户端通信的套接字
Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
//保存服务器端所有负责调用通信套接字.Receive()方法的线程
Dictionary<string, Thread> dicThread = new Dictionary<string, Thread>();
private void btnListen_Click(object sender, EventArgs e)
{
//创建负责监听的套接字,参数(使用ip4寻址协议,使用流式连接,使用tcp协议)
SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获得文本框中的IP地址对象
IPAddress address = IPAddress.Parse(txtIp.Text.Trim());
//创建包含IP和Port的网络节点对象
IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
//将负责监听的套接字绑定到唯一个IP和端口上
SocketWatch.Bind(endpoint);
//设置监听队列的长度
SocketWatch.Listen(10);
//创建负责监听的线程,并传入方法
threadWatch = new Thread(WatchConnecting);
threadWatch.IsBackground = true;//设置为后台线程
threadWatch.Start();//开启线程
showMsg("服务器启动监听成功");
}
void WatchConnecting()
{
while (true)
{
//开始监听客户端的请求,注意:accept方法会阻断当前线程
sokConnectin = SocketWatch.Accept();//一但监听到客户端的请求,就返回一个负责和该客户
//将与客户端通信的套接字对象sokConnectin添加到键值中,并以IP作为标识
dic.Add(sokConnectin.RemoteEndPoint.ToString(), sokConnectin);
//向列表控件中添加一个客户端ip端口字符串,作为客户的唯一标示
lbOnline.Items.Add(sokConnectin.RemoteEndPoint.ToString());
//端通信的sokconnection
threadRec = new Thread(receiveMsg);
showMsg("客户端连接成功");
threadRec.SetApartmentState(ApartmentState.STA);
threadRec.IsBackground = false;
threadRec.Start(sokConnectin);
dicThread.Add(sokConnectin.RemoteEndPoint.ToString(), threadRec);
}
}
void receiveMsg(object sokConnectinPara)
{
Socket sokConnectin = sokConnectinPara as Socket;
while (true)
{
//定义一个接收用的缓存(字节数组)
byte[] arrMsgRec = new byte[1024 * 1024];
//将接收到的数据存入arrMsgRec数组
int length = -1;
try
{
length = sokConnectin.Receive(arrMsgRec);
}
catch (SocketException ex)
{
showMsg("异常:" + ex.Message);
dic.Remove(sokConnectin.RemoteEndPoint.ToString());
dicThread.Remove(sokConnectin.RemoteEndPoint.ToString());
lbOnline.Items.Remove(sokConnectin.RemoteEndPoint.ToString());
break;
}
catch (Exception ex)
{
showMsg("异常:" + ex.Message);
break;
}
if (arrMsgRec[0] == 0)//判断发送过来的是文字还是文件
{
string msg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length - 1);
showMsg(msg);
}
else if (arrMsgRec[0] == 1)
{
SaveFileDialog sfd = new SaveFileDialog();
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string fileSavePath = sfd.FileName;//获得要保存的文件
//创建文件流,让后让文件流根据路径创建一个文件
using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
{
fs.Write(arrMsgRec, 1, length - 1);
showMsg("文件保存成功:" + fileSavePath);
}
}
}
}
}
void showMsg(string msg)
{
txtMsg.AppendText(msg + "\r\n");
}
private void btnSend_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(lbOnline.Text))
{
showMsg("请选择发送对象");
}
else
{
string msg = txtMsgSend.Text.Trim();
//将要发送的字符串转成UTF8对应的字节数组
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(msg);
string strClintKey = lbOnline.Text;
try
{
dic[strClintKey].Send(arrMsg);
}
catch (SocketException ex)
{
showMsg("异常:" + ex.Message);
}
catch (Exception ex)
{
showMsg("异常:" + ex.Message);
}
// sokConnectin.Send(arrMsg);
showMsg("发送了数据出去" + msg);
}
}
private void btnSendAll_Click(object sender, EventArgs e)
{
string msg = txtMsgSend.Text.Trim();
//将要发送的字符串转成UTF8对应的字节数组
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(msg);
foreach (Socket s in dic.Values)
s.Send(arrMsg);
// sokConnectin.Send(arrMsg);
showMsg("群发了:" + msg);
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.IO;
namespace MyChatroomClint
{
public partial class MyChatroomClient : Form
{
public MyChatroomClient()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;
}
Thread threadClinet = null;//客户端负责监听服务端线程的消息
Socket socketClient = null;
private void btnconnect_Click(object sender, EventArgs e)
{
IPAddress address = IPAddress.Parse(txtIp.Text.Trim());//获得IP
IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));//网络节点,创建客户端套接字
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//向指定的IP端口发送请求
socketClient.Connect(endpoint);
//创建线程
threadClinet = new Thread(receiveMsg);
threadClinet.IsBackground = true;
threadClinet.Start();
}
void receiveMsg()
{
while (true)
{
//定义一个接收用的缓存(字节数组)
byte[] arrMsgRec = new byte[1024 * 1024];
//将接收到的数据存入arrMsgRec数组
int length=socketClient.Receive(arrMsgRec);
string msg = System.Text.Encoding.UTF8.GetString(arrMsgRec,0,length);
showMsg(msg);
}
}
void showMsg(string msg)
{
txtMsg.AppendText(msg + "\r\n");
}
private void btnSend_Click(object sender, EventArgs e)
{
string msg = txtMsgSend.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(msg);
byte[] arrMsgSend = new byte[arrMsg.Length + 1];
arrMsgSend[0] = 0;
arrMsg.CopyTo(arrMsgSend,1);
// Buffer.BlockCopy(arrMsg, 0, arrMsgSend, 1, arrMsg.Length );
socketClient.Send(arrMsgSend);
showMsg("发送了数据出去" + msg);
}
//选择要发送的文件
private void btnChoseFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
txtFilePath.Text = ofd.FileName;
}
}
//向服务器端发送文件
private void btnSendFile_Click(object sender, EventArgs e)
{
//用文件流打开用户选择的文件
using (FileStream fs = new FileStream(txtFilePath.Text, FileMode.Open))
{
byte[] arrFile = new byte[1024 * 1024*2];//定义一个2M的缓存区
//将文件数据读到数组arrFile中,并获得真实长度Length
int length = fs.Read(arrFile,0,arrFile .Length);
byte[] arrFileSend = new byte[length + 1];
arrFileSend[0] = 1;//1代表发送的是文件数据
//将arrFile数组里的元素从第0个开始拷贝,拷贝到arrFileSend数组里,从第1个位置开始存放,一共拷贝length个数据
Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
//arrFile.CopyTo(arrFileSend, 1);//另外一种方法,从第一个位置开始复制
socketClient.Send(arrFileSend);//发送了包含表示符的文件
showMsg("文件发送完毕");
}
}
}
}
---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
来源:http://www.cnblogs.com/qwsdxz/p/3171553.html