通过c#编写的一个简单的socket通信测试工具,可用于测试TCP、UDP通信,可实现基本的聊天和文件发送等功能
参考:http://blog.csdn.net/chwei_cson/article/details/7737766
TCP服务端代码
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;
using System.Diagnostics;
namespace listen
{
public partial class tcpListen : Form
{
Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
private static int clientNum = 0;
Socket[] socConnection = new Socket[65535];
Thread threadWatch = null; // 负责监听客户端连接请求的 线程;
Socket socketWatch = null;
IPEndPoint localEP = null;
public tcpListen()
{
InitializeComponent();
//this.ControlBox = false; // 设置不出现关闭按钮
}
private void tcpListen_Load(object sender, EventArgs e)
{
if (this.DesignMode == false)
{
txtIP.SelectedIndex = 0;
IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in ipHostEntry.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{//筛选IPV4
txtIP.Items.Add(ip.ToString());
}
}
}
}
/// <summary>
/// 接受客户端消息并发送消息
/// </summary>
/// <param name="socketClientPara"></param>
private void btnListen_Click(object sender, EventArgs e)
{
//txtPort.Text = "89";
// 创建负责监听的套接字,注意其中的参数;
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.Invoke((EventHandler)delegate
{
if (txtIP.SelectedIndex == 0)
{
localEP = new IPEndPoint(IPAddress.Any, Convert.ToInt32(txtPort.Text.Trim()));
}
else
{
localEP = new IPEndPoint(IPAddress.Parse(txtIP.Text), Convert.ToInt32(txtPort.Text.Trim()));
}
});
try
{
// 将负责监听的套接字绑定到唯一的ip和端口上;
socketWatch.Bind(localEP);
}
catch (SocketException se)
{
MessageBox.Show("异常:" + se.Message);
return;
}
// 设置监听队列的长度;
socketWatch.Listen(10);
// 创建负责监听的线程;
threadWatch = new Thread(WatchConnecting);
threadWatch.IsBackground = true;
threadWatch.Start();
ShowMsg(Convert.ToString(localEP) + "服务器启动监听成功!"+"\r\n"+"等待客户端连接!");
}
/// <summary>
/// 监听客户端请求的方法;
/// </summary>
void WatchConnecting()
{
while (true) // 持续不断的监听客户端的连接请求;
{
// 开始监听客户端连接请求,Accept方法会阻断当前的线程;
socConnection[clientNum] = socketWatch.Accept();
this.Invoke((EventHandler)delegate
{
// 想列表控件中添加客户端的IP信息;
lbOnline.Items.Add(socConnection[clientNum].RemoteEndPoint.ToString());
// 将与客户端连接的 套接字 对象添加到集合中;
dict.Add(socConnection[clientNum].RemoteEndPoint.ToString(), socConnection[clientNum]);
ShowMsg(socConnection[clientNum].RemoteEndPoint.ToString() + "客户端连接成功!");
string temp = socConnection[clientNum].RemoteEndPoint.ToString() + "连接成功";
byte[] mesg = System.Text.Encoding.UTF8.GetBytes(temp); // 将要发送的字符串转换成Utf-8字节数组;
socConnection[clientNum].Send(mesg);
});
Thread thread = new Thread(new ParameterizedThreadStart(RecMsg));
thread.IsBackground = true;
thread.Start(socConnection[clientNum]);
dictThread.Add(socConnection[clientNum].RemoteEndPoint.ToString(), thread); // 将新建的线程 添加 到线程的集合中去。
clientNum++;
}
}
void RecMsg(object sokConnectionparn)
{
Socket socketServer = sokConnectionparn as Socket;
while (true)
{
// 定义一个2M的缓存区;
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
// 将接受到的数据存入到输入 arrMsgRec中;
int length = -1;
try
{
length = socketServer.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
}
catch (SocketException se)
{
// 从 通信套接字 集合中删除被中断连接的通信套接字;
dict.Remove(socketServer.RemoteEndPoint.ToString());
// 从通信线程集合中删除被中断连接的通信线程对象;
dictThread.Remove(socketServer.RemoteEndPoint.ToString());
this.Invoke((EventHandler)delegate
{
// 从列表中移除被中断的连接IP
lbOnline.Items.Remove(socketServer.RemoteEndPoint.ToString());
ShowMsg("异常1:" + se.Message);
});
break;
}
catch (Exception e)
{
// 从 通信套接字 集合中删除被中断连接的通信套接字;
dict.Remove(socketServer.RemoteEndPoint.ToString());
// 从通信线程集合中删除被中断连接的通信线程对象;
dictThread.Remove(socketServer.RemoteEndPoint.ToString());
this.Invoke((EventHandler)delegate
{
ShowMsg("异常2:" + e.Message);
// 从列表中移除被中断的连接IP
lbOnline.Items.Remove(socketServer.RemoteEndPoint.ToString());
});
break;
}
if (arrMsgRec[0] == 0) // 表示接收到的是数据;
{
this.Invoke((EventHandler)delegate
{
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length-1 );// 将接受到的字节数据转化成字符串;
this.showinfo.Text += "客户端" + socketServer.RemoteEndPoint.ToString() + "-->" + strMsg+"\r\n";
});
}
if (arrMsgRec[0] == 1) // 表示接收到的是文件;
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "所有文件(*.* )|*.*";
this.Invoke((EventHandler)delegate
{
if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{// 在上边的 sfd.ShowDialog() 的括号里边一定要加上 this 否则就不会弹出 另存为 的对话框,而弹出的是本类的其他窗口,,这个一定要注意!!!【解释:加了this的sfd.ShowDialog(this),“另存为”窗口的指针才能被SaveFileDialog的对象调用,若不加thisSaveFileDialog 的对象调用的是本类的其他窗口了,当然不弹出“另存为”窗口。】
string fileSavePath = sfd.FileName;// 获得文件保存的路径;
// 创建文件流,然后根据路径创建文件;
using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
{
fs.Write(arrMsgRec, 1, length - 1);
//fs.Write(arrMsgRec, 0, length);
ShowMsg("文件保存成功:" + fileSavePath + "\r\n");
fs.Flush();
fs.Close();
}
}
});
}
}
}
void ShowMsg(string str)
{
this.Invoke((EventHandler)delegate
{
txtInfo.AppendText(str + "\r\n");
});
}
private void btnSend_Click(object sender, EventArgs e)
{
string strMsg = "服务器"+Convert.ToString(localEP)+"-->" + txtMsgSend.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;
byte[] arrSendMsg = new byte[arrMsg.Length + 1];
arrSendMsg[0] = 0; // 表示发送的是消息数据
Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
string strKey = "";
strKey = txtCl.Text.Trim();
if (string.IsNullOrEmpty(strKey) || strKey == "客户端") // 判断是不是选择了发送的对象;
{
MessageBox.Show("请选择你要发送的客户端!!!");
}
else
{
dict[strKey].Send(arrSendMsg);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;
showinfo.AppendText(strMsg + "\r\n");
//txtMsgSend.Clear();
}
}
private void lbOnline_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
txtCl.Text = lbOnline.SelectedItem.ToString().Trim();
}
catch (Exception ex)
{ }
}
private void txtInfo_TextChanged(object sender, EventArgs e)
{
//选择richtextbox中内容的最后一个字节
this.txtInfo.Select(this.txtInfo.Text.Length, 1);
//设置滚动到当前位置
this.txtInfo.ScrollToCaret();
}
private void showinfo_TextChanged(object sender, EventArgs e)
{
//选择richtextbox中内容的最后一个字节
this.showinfo.Select(this.showinfo.Text.Length, 1);
//设置滚动到当前位置
this.showinfo.ScrollToCaret();
}
private void btnSendToAll_Click(object sender, EventArgs e)
{
string strMsg = "服务器"+Convert.ToString(localEP)+ "-->" + txtMsgSend.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;
byte[] arrSendMsg = new byte[arrMsg.Length + 1]; // 用来标识发送是数据而不是文件,如果没有这一段的客户端就接收不到消息了~~~
arrSendMsg[0] = 0; // 表示发送的是消息数据
Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
foreach (Socket s in dict.Values)
{
s.Send(arrSendMsg);
}
ShowMsg(strMsg);
//txtMsgSend.Clear();
}
private void btnSendFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "所有文件(*.* )|*.*";
ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filePath = "";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
filePath = ofd.FileName;
}
if (string.IsNullOrEmpty(filePath))
{
MessageBox.Show("请选择你要发送的文件!!!");
}
else
{
// 用文件流打开用户要发送的文件;
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
string fileName = System.IO.Path.GetFileName(filePath);
string fileExtension = System.IO.Path.GetExtension(filePath);
string strMsg = "服务器" + Convert.ToString(localEP) + "给你发送的文件为: " + fileName + "\r\n";
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;
byte[] arrSendMsg = new byte[arrMsg.Length + 1];
arrSendMsg[0] = 0; // 表示发送的是消息数据
Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
string strKey = "";
strKey = lbOnline.Text.Trim();
if (string.IsNullOrEmpty(strKey)) // 判断是不是选择了发送的对象;
{
MessageBox.Show("请选择你要发送的客户端!!!");
}
else
{
dict[strKey].Send(arrSendMsg);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;先发送文件名
byte[] arrFile = new byte[1024 * 1024 * 2];
int length = fs.Read(arrFile, 0, arrFile.Length); // 将文件中的数据读到arrFile数组中;
byte[] arrFileSend = new byte[length +1];
arrFileSend[0] = 1; // 用来表示发送的是文件数据;
Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
// 还有一个 CopyTo的方法,但是在这里不适合; 当然还可以用for循环自己转化;
// sockClient.Send(arrFileSend);// 发送数据到服务端;
dict[strKey].Send(arrFileSend);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;
//txtSelectFile.Clear();
}
}
}
filePath="";
}
private void tcpServerToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpListen fi = new tcpListen();
fi.Show();
}
private void tcpClientToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpClient fi = new tcpClient();
fi.Show();
}
private void udpServerToolStripMenuItem_Click(object sender, EventArgs e)
{
udpServer fi = new udpServer();
fi.Show();
}
private void udpClientToolStripMenuItem_Click(object sender, EventArgs e)
{
udpClient fi = new udpClient();
fi.Show();
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
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 listen
{
public partial class tcpClient : Form
{
public Socket newclient;
public bool Connected;
public Thread myThread;
public delegate void MyInvoke(string str);
public tcpClient()
{
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
byte[] data = new byte[1024];
newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string ip = txtServerIP.Text.Trim();
int port = Convert.ToInt32(txtServerPort.Text.Trim());
IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ip), port);
newclient.Connect(ie);
//connect.Enabled = false;
Connected = true;
}
catch (SocketException ex)
{
MessageBox.Show("连接服务器失败 " + ex.Message);
return;
}
ThreadStart myThreaddelegate = new ThreadStart(ReceiveMsg);
myThread = new Thread(myThreaddelegate);
myThread.IsBackground = true;
myThread.Start();
}
public void ReceiveMsg()
{
while (true)
{
// 定义一个2M的缓存区;
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
// 将接受到的数据存入到输入 arrMsgRec中;
int length = -1;
try
{
length = newclient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
}
catch (SocketException se)
{
showMsg("异常1;" + se.Message);
return;
}
catch (Exception e)
{
showMsg("异常2:" + e.Message);
return;
}
if (arrMsgRec[0] == 0) // 表示接收到的是消息数据; arrMsgRec[0] == 0)
{
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length - 1);// 将接受到的字节数据转化成字符串;
showMsg(strMsg);
}
if (arrMsgRec[0] == 1) // 表示接收到的是文件数据;
{
string SaveFileName = string.Empty;
try
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "所有文件(*.* )|*.*";
sfd.RestoreDirectory = true;
sfd.Title = "Where do you want to save the file?";
sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
this.Invoke((EventHandler)delegate
{
if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{// 在上边的 sfd.ShowDialog() 的括号里边一定要加上 this 否则就不会弹出 另存为 的对话框,而弹出的是本类的其他窗口,,这个一定要注意!!!【解释:加了this的sfd.ShowDialog(this),“另存为”窗口的指针才能被SaveFileDialog的对象调用,若不加thisSaveFileDialog 的对象调用的是本类的其他窗口了,当然不弹出“另存为”窗口。】
string fileSavePath = sfd.FileName;// 获得文件保存的路径;
// 创建文件流,然后根据路径创建文件;
using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
{
fs.Write(arrMsgRec, 1, length-1);
fs.Flush();
fs.Close();
}
showMsg("文件保存成功:" + fileSavePath);
}
});
}
catch (Exception aaa)
{
MessageBox.Show(aaa.Message);
if (myThread != null)
{
myThread.Abort();
}
break;
}
}
}
}
public void showMsg(string msg)
{
{
try
{
//在线程里以安全方式调用控件
if (txtReceiveMsg.InvokeRequired)
{
MyInvoke _myinvoke = new MyInvoke(showMsg);
txtReceiveMsg.Invoke(_myinvoke, new object[] { msg });
}
else
{
txtReceiveMsg.AppendText(msg + "\r\n");
}
}
catch (Exception ex)
{ }
}
}
private void btnSend_Click(object sender, EventArgs e)
{
try
{
string strMsg = txtSend.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
byte[] arrSendMsg = new byte[arrMsg.Length + 1];
arrSendMsg[0] = 0; // 用来表示发送的是消息数据
Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
newclient.Send(arrSendMsg); // 发送消息;
showMsg("我说:" + txtSend.Text);
}
catch (Exception ex)
{ }
}
private void txtReceiveMsg_TextChanged(object sender, EventArgs e)
{
//选择richtextbox中内容的最后一个字节
this.txtReceiveMsg.Select(this.txtReceiveMsg.Text.Length, 1);
//设置滚动到当前位置
this.txtReceiveMsg.ScrollToCaret();
}
private void tcpClient_FormClosing(object sender, FormClosingEventArgs e)
{
if (myThread != null)
{
myThread.Abort();
}
}
private void btnSendFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "所有文件(*.* )|*.*";
ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filePath = "";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
filePath = ofd.FileName;
}
if (string.IsNullOrEmpty(filePath))
{
MessageBox.Show("请选择你要发送的文件!!!");
}
else
{
// 用文件流打开用户要发送的文件;
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
string fileName = System.IO.Path.GetFileName(filePath);
string fileExtension = System.IO.Path.GetExtension(filePath);
string strMsg = "发送文件: " + fileName + "\r\n";
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;
byte[] arrSendMsg = new byte[arrMsg.Length + 1];
arrSendMsg[0] = 0; // 表示发送的是消息数据
Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
newclient.Send(arrMsg); // 发送消息;
byte[] arrFile = new byte[1024 * 1024 * 2];
int length = fs.Read(arrFile, 0, arrFile.Length); // 将文件中的数据读到arrFile数组中;
byte[] arrFileSend = new byte[length + 1];
arrFileSend[0] = 1; // 用来表示发送的是文件数据;
Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
// 还有一个 CopyTo的方法,但是在这里不适合; 当然还可以用for循环自己转化;
newclient.Send(arrFileSend);// 发送数据到服务端;
showMsg("我发送文件:" + filePath);
filePath = "";
}
}
}
private void tcpServerToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpListen fi = new tcpListen();
fi.Show();
}
private void tcpClientToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpClient fi = new tcpClient();
fi.Show();
}
private void udpServerToolStripMenuItem_Click(object sender, EventArgs e)
{
udpServer fi = new udpServer();
fi.Show();
}
private void udpClientToolStripMenuItem_Click(object sender, EventArgs e)
{
udpClient fi = new udpClient();
fi.Show();
}
}
}
UDP服务端代码
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;
using System.Diagnostics;
namespace listen
{
public partial class udpServer : Form
{
Dictionary<string, EndPoint> dict = new Dictionary<string, EndPoint>();
Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
Socket[] socConnection = new Socket[65535];
private static int clientNum = 0;
//private Thread myThread;
Socket socketWatch = null;
IPEndPoint localEP = null;
EndPoint remote = null;
public udpServer()
{
InitializeComponent();
}
private void udpServer_Load(object sender, EventArgs e)
{
if (this.DesignMode == false)
{
txtIP.SelectedIndex = 0;
IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in ipHostEntry.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{//筛选IPV4
txtIP.Items.Add(ip.ToString());
}
}
}
}
private void btnListen_Click(object sender, EventArgs e)
{
try
{
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
if (txtIP.SelectedIndex == 0)
{
localEP = new IPEndPoint(IPAddress.Any, Convert.ToInt32(txtPort.Text.Trim()));
}
else
{
localEP = new IPEndPoint(IPAddress.Parse(txtIP.Text), Convert.ToInt32(txtPort.Text.Trim()));
}
socketWatch.Bind(localEP);
ShowMsg(Convert.ToString(localEP) + "服务器启动监听成功!" + "\r\n" + "等待客户端连接");
if (socConnection[0] == null)
{
Thread thread = new Thread(new ParameterizedThreadStart(StartListener));
thread.IsBackground = true;
thread.Start(socConnection[clientNum]);
dictThread.Add(socConnection[clientNum].RemoteEndPoint.ToString(), thread); // 将新建的线程 添加 到线程的集合中去。
}
}
catch (Exception ex)
{ }
}
private void StartListener(object sokConnectionparn)
{
while (true)
{
try
{
string returnData = "";
byte[] bytes = new byte[1024];
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
remote = (EndPoint)(sender);
int recv = socketWatch.ReceiveFrom(bytes, ref remote);
returnData = Encoding.UTF8.GetString(bytes);
this.Invoke((EventHandler)delegate
{
showinfo.AppendText(remote.ToString() + "-->" + returnData.Trim());
showinfo.Text += System.Environment.NewLine;
if (!dict.ContainsValue(remote))
{
byte[] sendBytes = Encoding.UTF8.GetBytes(remote.ToString() + "加入链接");
socketWatch.SendTo(sendBytes, remote);
dict.Add(remote.ToString().Trim(), remote);
ShowMsg(remote.ToString() + "加入链接");
lbOnline.Items.Add(remote.ToString());
clientNum++;
Thread thread = new Thread(new ParameterizedThreadStart(StartListener));
thread.IsBackground = true;
thread.Start(socConnection[clientNum]);
dictThread.Add(remote.ToString(), thread); // 将新建的线程 添加 到线程的集合中去。
}
});
}
catch
{
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
if (this.DesignMode == false)
{
txtIP.SelectedIndex = 0;
IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in ipHostEntry.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{//筛选IPV4
txtIP.Items.Add(ip.ToString());
}
}
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//if (myThread != null)
//{
// myThread.Abort();
//}
}
private void lbOnline_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
txtCl.Text = lbOnline.SelectedItem.ToString().Trim();
}
catch (Exception ex)
{ }
}
private void txtInfo_TextChanged(object sender, EventArgs e)
{
//选择richtextbox中内容的最后一个字节
this.txtInfo.Select(this.txtInfo.Text.Length, 1);
//设置滚动到当前位置
this.txtInfo.ScrollToCaret();
}
private void showinfo_TextChanged(object sender, EventArgs e)
{
//选择richtextbox中内容的最后一个字节
this.showinfo.Select(this.showinfo.Text.Length, 1);
//设置滚动到当前位置
this.showinfo.ScrollToCaret();
}
private void btnSendToAll_Click(object sender, EventArgs e)
{
string strKey = "";
strKey = txtCl.Text.Trim();
byte[] sendBytes = Encoding.UTF8.GetBytes(socketWatch.LocalEndPoint.ToString() + "-->" + txtMsgSend.Text.Trim());
foreach (EndPoint s in dict.Values)
{
socketWatch.SendTo(sendBytes, s);
}
//txtMsgSend.Clear();
}
private void btnSendFile_Click(object sender, EventArgs e)
{
}
void ShowMsg(string str)
{
this.Invoke((EventHandler)delegate
{
txtInfo.AppendText(str + "\r\n");
});
}
private void tcpServerToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpListen fi = new tcpListen();
fi.Show();
}
private void tcpClientToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpClient fi = new tcpClient();
fi.Show();
}
private void udpServerToolStripMenuItem_Click(object sender, EventArgs e)
{
udpServer fi = new udpServer();
fi.Show();
}
private void udpClientToolStripMenuItem_Click(object sender, EventArgs e)
{
udpClient fi = new udpClient();
fi.Show();
}
private void btnSend_Click(object sender, EventArgs e)
{
string strKey = "";
strKey = txtCl.Text.Trim();
byte[] sendBytes = Encoding.UTF8.GetBytes(socketWatch.LocalEndPoint.ToString() + "-->" + txtMsgSend.Text.Trim());
if (string.IsNullOrEmpty(strKey) || strKey == "客户端") // 判断是不是选择了发送的对象;
{
MessageBox.Show("请选择你要发送的客户端!!!");
}
else
{
socketWatch.SendTo(sendBytes, dict[strKey]);
showinfo.AppendText(socketWatch.LocalEndPoint.ToString() + "-->" + txtMsgSend.Text.Trim() + "\r\n");
//txtMsgSend.Clear();
}
}
}
}
UDP客户端代码
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 listen
{
public partial class udpClient : Form
{
public Socket newclient = null;
public bool Connected;
public Thread myThread = null;
public delegate void MyInvoke(string str);
IPEndPoint ie = null;
public udpClient()
{
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
string ip = txtServerIP.Text.Trim();
int port = Convert.ToInt32(txtServerPort.Text.Trim());
ie = new IPEndPoint(IPAddress.Parse(ip), port);
newclient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message);
return;
}
}
public void ReceiveMsg()
{
//byte[] arrMsgRec = new byte[1024];
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint remote = (EndPoint)(sender);
//int recv = newclient.ReceiveFrom(arrMsgRec,ref remote);
//string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, recv);// 将接受到的字节数据转化成字符串;
//showMsg(strMsg);
while (true)
{
//定义一个2M的缓存区;
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
//将接受到的数据存入到输入 arrMsgRec中;
int length = -1;
try
{
length = newclient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
}
catch (SocketException se)
{
//showMsg("异常1;" + se.Message);
return;
}
catch (Exception e)
{
//showMsg("异常2:" + e.Message);
return;
}
if (arrMsgRec[0] != 1) // 表示接收到的是消息数据; arrMsgRec[0] == 0)
{
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, length);// 将接受到的字节数据转化成字符串;
showMsg(strMsg);
}
if (arrMsgRec[0] == 1) // 表示接收到的是文件数据;
{
try
{
SaveFileDialog sfd = new SaveFileDialog();
this.Invoke((EventHandler)delegate
{
if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{// 在上边的 sfd.ShowDialog() 的括号里边一定要加上 this 否则就不会弹出 另存为 的对话框,而弹出的是本类的其他窗口,,这个一定要注意!!!【解释:加了this的sfd.ShowDialog(this),“另存为”窗口的指针才能被SaveFileDialog的对象调用,若不加thisSaveFileDialog 的对象调用的是本类的其他窗口了,当然不弹出“另存为”窗口。】
string fileSavePath = sfd.FileName;// 获得文件保存的路径;
// 创建文件流,然后根据路径创建文件;
using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
{
fs.Write(arrMsgRec, 0, length);
showMsg("文件保存成功:" + fileSavePath);
}
}
});
}
catch (Exception aaa)
{
MessageBox.Show(aaa.Message);
if (myThread != null)
{
myThread.Abort();
}
break;
}
}
}
}
public void showMsg(string msg)
{
{
try
{
//在线程里以安全方式调用控件
if (txtReceiveMsg.InvokeRequired)
{
MyInvoke _myinvoke = new MyInvoke(showMsg);
txtReceiveMsg.Invoke(_myinvoke, new object[] { msg });
}
else
{
txtReceiveMsg.AppendText(msg + "\r\n");
}
}
catch (Exception ex)
{ }
}
}
//ThreadStart myThreaddelegate = new ThreadStart(ReceiveMsg);
private void btnSend_Click(object sender, EventArgs e)
{
try
{
if (newclient != null)
{
int m_length = txtSend.Text.Length;
byte[] data = new byte[m_length];
data = Encoding.UTF8.GetBytes(txtSend.Text.Trim());
newclient.SendTo(data, ie);
showMsg("我说:" + txtSend.Text);
//txtSend.Text = "";
if (myThread == null)
{
myThread = new Thread(ReceiveMsg);
myThread.IsBackground = true;
myThread.Start();
}
}
}
catch (Exception ex)
{ }
}
private void udpClient_FormClosing(object sender, FormClosingEventArgs e)
{
if (myThread != null)
{
myThread.Abort();
}
}
private void txtReceiveMsg_TextChanged(object sender, EventArgs e)
{
//选择richtextbox中内容的最后一个字节
this.txtReceiveMsg.Select(this.txtReceiveMsg.Text.Length, 1);
//设置滚动到当前位置
this.txtReceiveMsg.ScrollToCaret();
}
private void tcpServerToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpListen fi = new tcpListen();
fi.Show();
}
private void tcpClientToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpClient fi = new tcpClient();
fi.Show();
}
private void udpServerToolStripMenuItem_Click(object sender, EventArgs e)
{
udpServer fi = new udpServer();
fi.Show();
}
private void udpClientToolStripMenuItem_Click(object sender, EventArgs e)
{
udpClient fi = new udpClient();
fi.Show();
}
}
}