基于TCP、UDP使用C-开发的简易qq

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

TCP/UDP程序开发
使用C#制作简易qq
TCP、UDP程序开发一.实验课时
8学时
二.实验目的
开发TCP/UDP协议应用程序,掌握网络应用程序的工作原理。

通过本实验,深入理解TCP和UDP协议的异同点,了解网络协议的工作过程,学会网络通信编程的基本方法,能够编制网络应用程序。

三.实验内容
(1)了解和掌握“基于UDP——面向无连接的应用程序”和“基于TCP——面向连接的应用程序”的运行机制和编程方法。

(2)选择以下一个内容,编写一个网络通信应用程序
①聊天程序;
②邮件收发程序;
③HTTP服务器程序。

四.实验要求
(1)使用任意编程语言(如Java,C,VB,Delphi等)编写基于TCP或UDP协议的网络应用程序。

(2)总结实验过程,内容包括:方案、程序、调试、结果、分析、结论。

五.实验设备
(1)硬件要求:计算机、Internet网。

(2)软件要求:Windows操作系统、相关软件开发工具(如Microsoft Visual Studio,JDK等)。

六.预习要求
(1)复习TCP/UDP协议原理。

(2)复习应用进程跨越网络通信的基本编程方法。

(3)复习聊天、邮件、HTTP服务的相关原理。

(4)熟悉相关编程语言及编程工具环境。

七.注意事项
(1)遵守实验纪律,爱护实验设备。

(2)提交详细实验报告一份。

实验过程和结果不能简单地复制相关命令或内容,要有理解和分析。

八.程序代码
1.服务器端
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ;
using .Sockets;
using System.Threading;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Init();
tab2.Visible = true;
tab3.Visible = false;
tab1.Visible = false;
}
private void btnLog_Click(object sender, EventArgs e)
{
if (txtIP.Text == "" || txtPort.Text == "")
{
MessageBox.Show("请输入IP地址或端口号!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
return;
}
else
{
try
{
IPAddress ipadd = IPAddress.Parse(this.txtIP.Text);
int port = Convert.ToInt32(this.txtPort.Text);
tab3.Visible = true;
tab1.Visible = true;
this.Init2();
this.btnImgFile.Enabled = false;
this.Text = "服务器"+ DateTime.Now.ToString() + " "+ DateTime.Now.DayOfWeek.ToString();
richTextBox1.AppendText("System:服务器已进入聊天室!?<-"+ DateTime.Now.ToLongTimeString() + "->.....\r\n");
string SerIp = txtIP.Text.ToString();
string SerPort = txtPort.Text.ToString();
labip.Text = " IP地址:" + " " + SerIp + " ";
labport.Text = " 端口号:" + " " + SerPort;
}
catch (Exception)
{
MessageBox.Show("您输入的IP地址或端口号不正确,\n请重新输入!", "错误 ", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
//重置服务器信息
private void btnResent_Click_1(object sender, EventArgs e)
{
txtIP.Clear();
txtPort.Clear();
}
private void Init()
{
richTextBox1.Visible = false;
txt1_sendinfo.Visible = false;
}
private void Init2()
{
richTextBox1.Visible = true;
txt1_sendinfo.Visible = true;
}
private OpenFileDialog openfiledialog = new OpenFileDialog();
private SaveFileDialog savefiledialog = new SaveFileDialog();
private byte[] img;//传输图片用字节数组
private int imgflag = 0;
private FileStream fstream;
public delegate void UpdateRichTextBox(string msg);//异步委托代理
public delegate void UpdateImg(Stream s);
private Socket socket; //服务器端套接字
private Socket clientSocket; //客户端连接套接字
private Thread thread;
//启动服务器,开始监听
private void btn_start_Click(object sender, EventArgs e)
{
try
{
IPAddress ip = IPAddress.Parse(this.txtIP.Text);
IPEndPoint server = new IPEndPoint(ip, Int32.Parse(this.txtPort.Text));
//创建服务器套接字
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(server);//绑定端口号
socket.Listen(10);
thread = new Thread(new ThreadStart(AcceptMessage));
thread.Start();//开始监听
this.Text = " 服务器Taking....";
richTextBox1.Clear();
richTextBox1.AppendText("System:服务器已启动!<-"+ DateTime.Now.ToLongTimeString() + "->.....\r\n");
btnImgFile.Enabled = true;
btn_start.Enabled = false;
btn_stop.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show("服务器: " + ex.Message);
this.btn_start.Enabled = true;
}
}
//接收客户端信息
public void AcceptMessage() //异步接收信息后台线程方法
{
this.clientSocket = socket.Accept();
this.richTextBox1.Clear();
richTextBox1.AppendText("System:服务器连接成功!?<-"+ DateTime.Now.ToLongTimeString() + "->.....\r\n");
while (true)
{
try
{
if(this.clientSocket == null|| this.clientSocket.Connected == false)
break;
NetworkStream netStream = new NetworkStream(this.clientSocket);//通过clientSocket对象获取NetworkStream对象
//得到一条消息的长度
byte[] dataSize = new byte[4];
netStream.Read(dataSize, 0, 4);
int size = System.BitConverter.ToInt32(dataSize, 0);
//循环接收直到一条完整的消息全部读入到字节数组中
byte[] message = new byte[size];
int dataleft = size;
int start = 0;
if (size > 0)
{
while (dataleft > 0)
{
int recv = netStream.Read(message, start, dataleft);
start += recv;
dataleft -= recv;
}
if (message[0] == 101)//101代表传输图片
{
MemoryStream ms = new MemoryStream(message, 1, message.Length - 1);
richTextBox1.BeginInvoke(new UpdateImg(ViewImg), new object[] { ms });
}
else//默认进行普通传输
{
string Msg = System.Text.Encoding.Unicode.GetString(message, 1, message.Length - 1);
this.richTextBox1.BeginInvoke(new
UpdateRichTextBox(UpdateMessage), new object[] { Msg });
}
}
Thread.Sleep(100);
}
catch (.Sockets.SocketException se)
{
MessageBox.Show("服务器:" + se.Message);
}
}
}
//点击“发送”按钮
private void btn_send_Click(object sender, EventArgs e)
{
if (txt1_sendinfo.Text == "")
{
MessageBox.Show("请先输入内容!");
txt1_sendinfo.Clear();
txt1_sendinfo.Focus();
return;
}
if (imgflag == 1)
{
//发送图片?
byte[] imgSize = new byte[4];
//将32位整数值转换为字节数组
imgSize = System.BitConverter.GetBytes(img.Length + 1);//其中加1是因为后面了一个101做分隔符
try
{
NetworkStream netStream = new NetworkStream(clientSocket);
netStream.Write(imgSize, 0, 4);
netStream.WriteByte(101);//分隔符
netStream.Write(img, 0, img.Length);
netStream.Flush();
this.richTextBox1.SelectionColor = Color.SteelBlue;
this.richTextBox1.AppendText("服务器<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n");
this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;
Clipboard.SetDataObject(Image.FromStream(fstream));
richTextBox1.Paste();
this.richTextBox1.SelectionColor = Color.SteelBlue;
this.richTextBox1.AppendText("\n");
fstream.Flush();
fstream.Close();//此流必须在这里才可以消除
txt1_sendinfo.Paste();
this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;
this.richTextBox1.Focus();
this.txt1_sendinfo.Text = "";
this.txt1_sendinfo.Focus();
imgflag = 0;//复原
return;//不执行后面的传输文本信息
}
catch (System.Exception ex)
{
MessageBox.Show("服务器:" + ex.Message);
}
}
//发送文本信息
this.richTextBox1.SelectionColor = Color.SteelBlue;
string str = "服务器<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n"+ txt1_sendinfo.Text;
int i = str.Length;
if (i == 0)
{
return;
}
else
{
//因为str为Unicode编码,每个字符占2个字节,所以实际字节数应为字符个数*2 i *= 2;
}
byte[] dataSize = new byte[4];
//将32位整数值转换为字节数组
dataSize = System.BitConverter.GetBytes(i + 1);//其中加1是因为后面写了一个1做分隔符
byte[] sendbytes = System.Text.Encoding.Unicode.GetBytes(str);
try
{
NetworkStream netStream = new NetworkStream(clientSocket);
netStream.Write(dataSize, 0, 4);
netStream.WriteByte(1);//分隔符
netStream.Write(sendbytes, 0, sendbytes.Length);
netStream.Flush();
richTextBox1.SelectionColor = Color.SteelBlue;
this.richTextBox1.AppendText(str + "\n");
this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;
this.richTextBox1.Focus();
this.txt1_sendinfo.Rtf = "";
this.txt1_sendinfo.Focus();
}
catch (System.Exception ex)
{
MessageBox.Show("服务器:" + ex.Message);
}
}
//断开连接
private void btn_stop_Click(object sender, EventArgs e)
{
socket.Close();
thread.Abort();
thread.Join(10);
this.btn_start.Enabled = true;
btn_stop.Enabled = false;
this.btnImgFile.Enabled = false;
this.Text = " 服务器"+ DateTime.Now.ToString() + " "+ DateTime.Now.DayOfWeek.ToString();
this.richTextBox1.AppendText("System:服务器断开连接!<-"+ DateTime.Now.ToLongTimeString() + "->..... \r\n");
}
//接收文本
private void UpdateMessage(string strmsg) //将异步接收到的信息显示在文本框里
{
this.richTextBox1.SelectionColor = Color.LightCoral;
this.richTextBox1.AppendText(strmsg + "\n");
this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;
this.richTextBox1.Focus();
this.txt1_sendinfo.Focus();
}
//接收图片信息
private void ViewImg(Stream s) //将异步接收到的信息显示在文本框里
{
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.SelectionColor = Color.LightCoral;
richTextBox1.AppendText("服务器接收图片<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n");
Clipboard.SetDataObject(Image.FromStream(s));//利用剪切板
richTextBox1.Paste();
richTextBox1.SelectionColor = Color.LightCoral;
richTextBox1.AppendText("\n");
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.Focus();
txt1_sendinfo.Focus();
}
//上传图片文件中的图片
private void btnImgFile_Click(object sender, EventArgs e)
{
openfiledialog.Filter = "所有文件t(*.*)|*.*|位图文(*.bmp)|*.bmp|文件t (.jpg)|*.jpg|文件t(.gif)|*.gif";
if (openfiledialog.ShowDialog() == DialogResult.OK)
{
String strpath = openfiledialog.FileName;
fstream = new FileStream(strpath, FileMode.Open);
BinaryReader breader = new BinaryReader(fstream);
img = breader.ReadBytes((int)fstream.Length);
Clipboard.SetDataObject(Image.FromStream(fstream));
txt1_sendinfo.Paste();
imgflag = 1;
}
}
//退出聊天室
private void btn_Exit_Click(object sender, EventArgs e)
{
if (btn_stop.Enabled != true)
{
this.Close();
Application.Exit();
}
else
{
MessageBox.Show("请先断开连接!");
return;
}
}
//取消发送
private void btnRest_Click(object sender, EventArgs e)
{
txt1_sendinfo.Clear();
}
//清屏
private void btnClear_Click(object sender, EventArgs e)
{
this.richTextBox1.Clear();
}
}
}
2.客户端
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ;
using .Sockets;
using System.Threading;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Init();
tab2.Visible = true;
tab3.Visible = false;
tab1.Visible = false;
}
private void Init()
{
this.richTextBox1.Visible = false;
this.txt2_send.Visible = false;
}
private void Init2()
{
this.richTextBox1.Visible = true;
this.txt2_send.Visible = true;
}
//登录聊天室
private void btnLog_Click(object sender, EventArgs e)
{
if (txtIP.Text == "" || txtPort.Text == "")
{
MessageBox.Show("服务器信息不能为空!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
return;
}
if (txtName.Text == "")
{
MessageBox.Show("请输入您的呢称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
return;
}
else
{
try
{
IPAddress ipadd = IPAddress.Parse(this.txtIP.Text);
int port = Convert.ToInt32(this.txtPort.Text);
userName = txtName.Text.ToString();
tab1.Visible = true;
this.Init2();
tab3.Visible = true;
this.btnImgFile.Enabled = false;
this.Text = " " + userName + " " + DateTime.Now.ToString() + " " + DateTime.Now.DayOfWeek.ToString();
richTextBox1.AppendText("System:"+ userName + " 已进入聊天室!<-"+ DateTime.Now.ToLongTimeString() + "->.....\r\n");
string SerIp = txtIP.Text.ToString();
string SerPort = txtPort.Text.ToString();
lbSerIp.Text = " IP地址 :" + " " + SerIp + " ";
lbSerPort.Text = " 端口号?:" + " " + SerPort;
}
catch (Exception)
{
MessageBox.Show("您输入的服务器信息不合法,\n请重新输入!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
//重置服务器信息和昵称
private void btnResent_Click(object sender, EventArgs e)
{
txtIP.Clear();
txtPort.Clear();
txtName.Clear();
}
private OpenFileDialog openfiledialog = new OpenFileDialog();
private SaveFileDialog savefiledialog = new SaveFileDialog();
private byte[] img;//保存传图片时的字节数组
private int imgflag = 0;
private FileStream fstream;
public delegate void UpdateMessage(string msg);
public delegate void UpdateImg(Stream s);
private Socket socket;
private Thread thread;
public string userName;
//与服务器连接
private void btn_req_Click(object sender, EventArgs e)
{
try
{
IPAddress ip = IPAddress.Parse(this.txtIP.Text);
IPEndPoint server = new IPEndPoint(ip, Int32.Parse(this.txtPort.Text));
//创建客户端套接字
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(server);//连接
thread = new Thread(new ThreadStart(AcceptMessage));
thread.Start();
this.Text = " " + userName + " Taking....";
richTextBox1.Clear();
richTextBox1.AppendText("System:" + userName + " 连接到服务器!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");
btn_req.Enabled = false;
btn_close.Enabled = true;
btnImgFile.Enabled = true;
}
catch
{
richTextBox1.Clear();
richTextBox1.AppendText("System:" + userName + " 未连接上服务器!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");
return;
}
}
//接收后台接收消息
public void AcceptMessage() //异步接收信息后台线程方法
{
while (true)
{
try
{
if (this.socket == null || this.socket.Connected == false)
{
richTextBox1.Clear();
richTextBox1.AppendText("System:" + userName + "未连接上服务器!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");
break;
}
NetworkStream netStream = new NetworkStream(this.socket);//必须放在if后,this.socket可能没实例化
//得到一条消息的长度
byte[] dataSize = new byte[4];//前4字节代表后面字节总数,发送时骸已经处理过了
try
{
netStream.Read(dataSize, 0, 4);
}
catch (Exception)
{
}
int size = System.BitConverter.ToInt32(dataSize, 0);
//循环接收直到一条完整的消息全部读入到字节数组中
byte[] message = new byte[size];
int dataleft = size;
int start = 0;
while (dataleft > 0)
{
int recv = netStream.Read(message, start, dataleft);
start += recv;
dataleft -= recv;
}
if (message[0] == 101)//101代表传输图片
{
MemoryStream ms = new MemoryStream(message, 1, message.Length - 1); richTextBox1.BeginInvoke(new UpdateImg(ViewImg), new object[] { ms });
}
else//默认进行普通传输
{
string Msg = System.Text.Encoding.Unicode.GetString(message, 1, message.Length - 1);
richTextBox1.BeginInvoke(new UpdateMessage(ViewMessage), new object[] { Msg });
}
Thread.Sleep(100);
}
catch (.Sockets.SocketException ex)
{
MessageBox.Show(userName + ":" + ex.Message);
}
}
}
//传输文件
private void ViewMessage(string msg)
{
richTextBox1.SelectionColor = Color.SteelBlue;
richTextBox1.AppendText(msg + "\n");
richTextBox1.SelectionStart = richTextBox1.Text.Length;//定位到最后,保持最新消息可见
richTextBox1.Focus();
txt2_send.Focus();
}
//接收图片信息
private void ViewImg(Stream s)
{
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.SelectionColor = Color.SteelBlue;
richTextBox1.AppendText(userName + "接收图片<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n");
Clipboard.SetDataObject(Image.FromStream(s));//利用剪切板
richTextBox1.Paste();
richTextBox1.SelectionColor = Color.SteelBlue;
richTextBox1.AppendText("\n");
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.Focus();
txt2_send.Focus();
}
//点击发送按钮
private void btn_send_Click(object sender, EventArgs e)
{
if (txt2_send.Text == "")
{
MessageBox.Show("请先输入内容!");
txt2_send.Clear();
txt2_send.Focus();
return;
}
if (imgflag == 1)//imgflag的值在方法tnImgFile_Click中可能改变
{//当传输图片时
byte[] imgSize = new byte[4];
//将32位整数值转换为字节数组
imgSize = System.BitConverter.GetBytes(img.Length + 1);//后面一个标识数:101
try
{
NetworkStream netStream = new NetworkStream(this.socket);
netStream.Write(imgSize, 0, 4);
netStream.WriteByte(101);//标识数
netStream.Write(img, 0, img.Length);
netStream.Flush();
this.richTextBox1.SelectionColor = Color.LightCoral;
this.richTextBox1.AppendText(userName + "<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n");
this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;
Clipboard.SetDataObject(Image.FromStream(fstream));
richTextBox1.Paste();
richTextBox1.SelectionColor = Color.LightCoral;
this.richTextBox1.AppendText("\n");
fstream.Flush();
fstream.Close();//此流必须在这里才可以消除
txt2_send.Paste();
this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;
this.richTextBox1.Focus();
this.txt2_send.Text = "";
this.txt2_send.Focus();
imgflag = 0;//复原
return;//不执行后面的传输文本信息
}
catch (System.Exception ex)
{
MessageBox.Show("服务器:" + ex.Message);
}
}
//发送文本信息时
this.richTextBox1.SelectionColor = Color.LightCoral;
string str = userName + "<-" + DateTime.Now.ToLongTimeString() + "->:阰\r\n" + txt2_send.Text;
int i = str.Length;
if (i == 0)
{
return;
}
else
{
//因为str为Unicode编码,每个字符占2个字节,所以实际字节数应为字符个数*2 i *= 2;
}
byte[] dataSize = new byte[4];
//将32位整数值转换为字节数组
dataSize = System.BitConverter.GetBytes(i + 1);//后面一个标识数:1 byte[] sendbytes = System.Text.Encoding.Unicode.GetBytes(str);
try
{
NetworkStream netStream = new NetworkStream(this.socket);
netStream.Write(dataSize, 0, 4);
netStream.WriteByte(1);//标识数
netStream.Write(sendbytes, 0, sendbytes.Length);
netStream.Flush();
richTextBox1.SelectionColor = Color.LightCoral;
this.richTextBox1.AppendText(str + "\n");
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.Focus();
this.txt2_send.Rtf = "";
txt2_send.Focus();
}
catch (System.Exception ex)
{
MessageBox.Show(userName + ":" + ex.Message);
}
}
//发送图片按钮
private void btnImgFile_Click(object sender, EventArgs e)
{
openfiledialog.Filter = "所有文件t(*.*)|*.*|位图文件t(*.bmp)|*.bmp|文件t (.jpg)|*.jpg|文件t(.gif)|*.gif";
if (openfiledialog.ShowDialog() == DialogResult.OK)
{
String strpath = openfiledialog.FileName;
fstream = new FileStream(strpath, FileMode.Open);//此行和下一行是关键,得到文件字节数组
BinaryReader breader = new BinaryReader(fstream);
img = breader.ReadBytes((int)fstream.Length);//得到文件数组
Clipboard.SetDataObject(Image.FromStream(fstream));
txt2_send.Paste();
imgflag = 1;
}
}
//断开和服务器端连接ó
private void btn_close_Click(object sender, EventArgs e)
{
socket.Close();
thread.Abort();
thread.Join(10);
this.btn_req.Enabled = true;
btn_close.Enabled = false;
btnImgFile.Enabled = false;
this.Text = " "+ userName + " "+ DateTime.Now.ToString() + " "+ DateTime.Now.DayOfWeek.ToString();
this.richTextBox1.AppendText("System:" + userName + " 断开与服务器的连接!<-" + DateTime.Now.ToLongTimeString() + "->..... \r\n");
}
//退出聊天室
private void btn_Exit_Click(object sender, EventArgs e)
{
if (btn_close.Enabled != true)
{
this.Close();
Application.Exit();
}
else
{
MessageBox.Show("请先断开连接!");
return;
}
}
//取消发送
private void btnRest_Click(object sender, EventArgs e) {
txt2_send.Clear();
}
//清屏
private void btnClear_Click(object sender, EventArgs e) {
this.richTextBox1.Clear();
}
}
}
九.截图
十.实验心得
(注:可编辑下载,若有不当之处,请指正,谢谢!)。

相关文档
最新文档