




已阅读5页,还剩18页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
网络与通信课程实验报告实验2:Socket通信编程姓名沈文潇院系计算机学院学号13121602任课教师张瑞指导教师张瑞实验地点计706实验时间周四0304实验课表现出勤、表现得分(10)实验报告得分(40)实验总分操作结果得分(50)实验目的:1. 掌握Socket编程过程;2. 编写简单的网络应用程序。实验内容:利用你选择的任何一个编程语言,分别基于TCP 和UDP 编写一个简单的Client/Server 网络应用程序。具体程序要求参见实验指导书。要求以附件形式给出:l 系统概述:运行环境、编译、使用方法、实现环境、程序文件列表等;l 主要数据结构;l 主要算法描述; l 用户使用手册;l 程序源代码;实验要求:(学生对预习要求的回答)(10分)得分:l Socket编程客户端的主要步骤TCP编程的客户端一般步骤是:1、创建一个socket;2、设置socket属性;3、绑定IP地址、端口等信息到socket上;4、设置要连接的对方的IP地址和端口等属性;5、连接服务器;6、收发数据;7、关闭网络连接。UDP编程的客户端一般步骤是:1、创建一个socket;2、设置socket属性;3、绑定IP地址、端口等信息到socket上; 4、设置对方的IP地址和端口等属性;5、发送数据;6、关闭网络连接。l Socket编程服务器端的主要步骤TCP编程的服务器端一般步骤是:1、创建一个socket2、设置socket属性;3、绑定IP地址、端口等信息到socket上;4、开启监听;5、接收客户端上来的连接;6、收发数据;7、关闭网络连接;8、关闭监听。UDP编程的服务器端一般步骤是:1、创建一个socket;2、设置socket属性;3、绑定IP地址、端口等信息到socket上;4、循环接收数据;5、关闭网络连接;实验过程中遇到的问题如何解决的?(10分)得分:问题1:同步调用接收消息函数时,UI假死。问题描述:如果以单线程编程的逻辑,调用接收消息函数时,如果接收不到消息,程序会停在这一步,相当C语言编程时等待用户输入,这样一来界面将失去对用户操作的相应,造成UI假死。解决方案:TCP接收消息使用异步调用,再通过回调函数来处理接收到的消息;UDP接收消息则采用开启接收消息的后台线程来防止UI假死。问题2:基于TCP协议的用户认证问题。问题描述:根据实验要求,连接时需要实现用户认证,但客户端与服务端建立连接的相关函数里(基于.NET FrameWork 4.5 的C#语言),并没有提供传递验证信息的参数或字段。解决方案:服务端将先与客户端建立连接,但第一时间会发送给客户端消息:请求用户名和密码,客户端在收到这个消息时将第一时间想服务端提供用户输入的用户名和密码,如果客户端提供的用户名或密码不正确,或拒绝提供,服务端将主动断开与服务端的连接。问题3:基于UDP的服务端的接收消息线程无法终止。问题描述:UDP的服务端接收消息采用后台线程来处理,线程执行的函数是一个不同接收消息并处理的死循环,所以当程序主窗体关闭后,改线程无法正常终止。解决方案:由于接收不到消息线程会一直停在那儿等待消息,故无法从外部通知线程主动终止,只能从外部强行杀死改线程,但这不是一个安全的方案。本次实验的体会(结论)(10分)得分:平心而论此次实验课题的设计并不合理,如果按照大二正常的课程顺序学习,现在的我们并不具备Socket编程的能力,即使我们能通过很短的时间,掌握实验指导书上的编程示例,也不具备将其改写为图像化界面程序的能力,最早涉及到可视化编程的课程也只是本学期初学的Windows编程,且刚掌握到简单控件的使用。 因为我有幸在大二时提前选修了面向大三学生的.Net程序设计,才得以用C#语言完成这次实验。我并不明白设计这个实验课题的老师的用意,或许是鼓励我们自学课程以外的知识,或许是让我们短时间内掌握Socket编程,但可以肯定的是,我身边一些很优秀的同学将很难完成这个实验。所以学生在这里斗胆向老师提出建议,降低这个实验的要求,不鼓励使用图形界面,而是统一写控制台程序来完成实验,这样我们将有机会把更多的精力放在学习Socket编程上,而不会因为不会做图形界面而吃亏。思考题:(10分)思考题1:(4分)得分:你所用的编程语言在Socket通信中用到的主要类及其主要作用。System.Net.Sockets.Socket:实现 Berkeley 套接字接口。System.Net.IPAddress:提供网际协议 (IP) 地址。System.Net.Dns:提供简单的域名解析功能。System.Net.IPEndPoint:将网络端点表示为 IP 地址和端口号。System.Net.Sockets.UdpClient:提供用户数据报协议 (UDP) 网络服务。思考题2:(6分)得分:说明TCP和UDP编程的主要差异和特点。TCP面向连接通信,所以握手过程会消耗资源,过程为可靠连接,不会丢失数据,适合大数据量交换,TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地发往网络上的其他计算机,对可靠性要求高的数据通信系统往往使用TCP协议传输数据。UDP面向非可靠连接,会丢包,没有校验,速度快,无须握手过程,适用于一次只传送少量数据、对可靠性要求不高的应用环境。指导教师评语:日期: 附件:系统概述:运行环境、编译、使用方法、实现环境、程序文件列表等;运行环境:Windows7系统下的编译:C#使用方法:为一般窗口程序,双击即可实现环境:Microsoft Visio Studio程序文件列表:主要数据结构;TCP服务端:public partial class TcpServerForm : Formprivate Socket _server;private Socket _client;private byte _receiveData = new byte1024;private string _username;private string _password;private bool _needPasswordl;private bool _passwordWrong;public TcpServerForm()private void TcpReceiveForm_Load(object sender, EventArgs e)private void btnListen_Click(object sender, EventArgs e)private void btnDisconnect_Click(object sender, EventArgs e)void AcceptedConnection(IAsyncResult iar)void ReceivedData(IAsyncResult iar)void SentData(IAsyncResult iar)void ProcessDisconnection()private void txtUserName_TextChanged(object sender, EventArgs e)private void txtPassword_TextChanged(object sender, EventArgs e)private void lblUserName_Click(object sender, EventArgs e)private void gnConnectInfo_Enter(object sender, EventArgs e)private void lbMessage_SelectedIndexChanged(object sender, EventArgs e)private void lbNativeIP_SelectedIndexChanged(object sender, EventArgs e)private void lbConnectLog_SelectedIndexChanged(object sender, EventArgs e)TCP客户端:public partial class TcpClientForm : FormSocket _client;byte _receivedData = new byte1024;public TcpClientForm()private void btnConnect_Click(object sender, EventArgs e)private void btnDisconnect_Click(object sender, EventArgs e)private void btnSend_Click(object sender, EventArgs e)void Connected(IAsyncResult iar)void ReceivedData(IAsyncResult iar)void SentData(IAsyncResult iar)void ProcessDisconnection()private void txtIP_TextChanged(object sender, EventArgs e)UDP接收端:public partial class UdpReceiveForm : Formprivate bool ReadFlag = true;private Thread th;private IPEndPoint remote;private UdpClient server;private int count = 0;private double num;public UdpReceiveForm()private void read()private void btnReceive_Click(object sender, EventArgs e)private void UdpReceiveForm_FormClosing(object sender, FormClosingEventArgs e)UDP发送端:public partial class UdpSendForm : Formpublic UdpSendForm()private void btnSend_Click(object sender, EventArgs e)private void txtIP_TextChanged(object sender, EventArgs e)private void lblInfo_Click(object sender, EventArgs e)主要算法描述; 异步调用与回调(部分):TCP服务端:_server.BeginAccept(new AsyncCallback(AcceptedConnection), _server);/异步调用,开始接收连接 - void AcceptedConnection(IAsyncResult iar)_client.BeginSend(sendMessage, 0, sendMessage.Length, SocketFlags.None, new AsyncCallback(SentData), _client);/异步调用,消息发送完毕执行-void SentData(IAsyncResult iar)_client.BeginReceive(_receiveData, 0, _receiveData.Length, SocketFlags.None, new AsyncCallback(ReceivedData), _client);/密码正确,开始接收消息-void ReceivedData(IAsyncResult iar)用户使用手册;TCP客户端、TCP服务端:1、用户打开TCP客户端并且输入服务端IP、用户名与密码(密码事先在服务端设置好);2、服务端点击“开始监听”,客户端点击“连接”;3、客户端在消息框内输入消息,点击“发送”,则消息发送到服务端,;4、服务端接收并且在“接收到的消息”框里显示消息与发送消息时的日期;注:客户端与服务端均能断开连接。一、 UDP发送端、UDP接收端:1、 用户打开UDP发送端并且输入目标IP、需发送的消息;2、 点击“发送按钮”;3、 接收端点击“接收”则接收到消息。程序源代码;Tcp服务端:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Net;using System.Net.Sockets;namespace TCP服务端public partial class TcpServerForm : Formprivate Socket _server;private Socket _client;private byte _receiveData = new byte1024;private string _username;private string _password;private bool _needPasswordl;private bool _passwordWrong;public TcpServerForm()InitializeComponent();private void TcpReceiveForm_Load(object sender, EventArgs e)IPAddress addressList = Dns.GetHostAddresses(Dns.GetHostName();foreach (IPAddress ip in addressList) if (ip.ToString().Length = 15)lbNativeIP.Items.Insert(0, ip.ToString(); btnDisconnect.Enabled = false;private void btnListen_Click(object sender, EventArgs e)_username = txtUserName.Text;_password = txtPassword.Text; /设置用户名与密码_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);/新建协议为tcp的socket _server.Bind(new IPEndPoint(IPAddress.Any, 8000);/监听端口为8000_server.Listen(5);/开始监听_server.BeginAccept(new AsyncCallback(AcceptedConnection), _server);/异步调用,开始接收连接this.lblStatus.Text = 开始监听.;btnListen.Enabled = false;txtUserName.Enabled = false;txtPassword.Enabled = false;_needPasswordl = true;_passwordWrong = false;/处理逻辑private void btnDisconnect_Click(object sender, EventArgs e)_client.Close();_needPasswordl = true;_server.BeginAccept(new AsyncCallback(AcceptedConnection), _server);this.lblStatus.Text = 开始监听.;void AcceptedConnection(IAsyncResult iar)_client = (Socket)iar.AsyncState).EndAccept(iar);/终止接收连接this.lblStatus.Text = 连接到: + _client.RemoteEndPoint.ToString();/解析对方地址与端口byte sendMessage = Encoding.Default.GetBytes(DateTime.Now.TimeOfDay + :请发送用户与密码);/向客户端提出发送密码的请求lbConnectLog.Items.Insert(0, 连接到: + _client.RemoteEndPoint.ToString();_client.BeginSend(sendMessage, 0, sendMessage.Length, SocketFlags.None, new AsyncCallback(SentData), _client);/异步调用,消息发送完毕执行SentDatabtnDisconnect.Enabled = true;void ReceivedData(IAsyncResult iar)_client = (Socket)iar.AsyncState;int recv = 0;tryrecv = _client.EndReceive(iar);catchProcessDisconnection();/解析消息if (recv = 0)/解析失败_client.Close();this.lblStatus.Text = 等待连接.;_server.BeginAccept(new AsyncCallback(AcceptedConnection), _server);return;string receiveMessage = Encoding.Default.GetString(_receiveData, 0, recv);this.lbMessage.Items.Insert(0,receiveMessage);/将消息放入消息列表byte feedbackMessage;if(_needPasswordl)string receiveUsername = receiveMessage.Substring(receiveMessage.LastIndexOf(:) + 1, receiveMessage.IndexOf(#) - (receiveMessage.LastIndexOf(:) + 1);string receivePassword = receiveMessage.Substring(receiveMessage.IndexOf(#) + 1, receiveMessage.Length - (receiveMessage.IndexOf(#) + 1);if(receiveUsername = _username & receivePassword = _password)_needPasswordl = false;_passwordWrong = false;feedbackMessage = Encoding.Default.GetBytes(DateTime.Now.TimeOfDay + :验证成功_ + receiveMessage);_client.BeginSend(feedbackMessage, 0, feedbackMessage.Length, SocketFlags.None, new AsyncCallback(SentData), _client);return;elsethis.lbConnectLog.Items.Insert(0, receiveUsername + # + receivePassword + 验证失败);feedbackMessage = Encoding.Default.GetBytes(DateTime.Now.TimeOfDay + :验证失败_ + receiveMessage);_passwordWrong = true;_client.BeginSend(feedbackMessage, 0, feedbackMessage.Length, SocketFlags.None, new AsyncCallback(SentData), _client);return;feedbackMessage = Encoding.Default.GetBytes(DateTime.Now.TimeOfDay + :成功接收 + receiveMessage);_client.BeginSend(feedbackMessage, 0, feedbackMessage.Length, SocketFlags.None, new AsyncCallback(SentData), _client);void SentData(IAsyncResult iar)_client = (Socket)iar.AsyncState;int sent = _client.EndSend(iar);if (_passwordWrong)lbConnectLog.Items.Insert(0, 主动断开连接 + _client.RemoteEndPoint.ToString();_client.Close();_needPasswordl = true;_server.BeginAccept(new AsyncCallback(AcceptedConnection), _server);/重新开始接收新的连接ProcessDisconnection();return;_client.BeginReceive(_receiveData, 0, _receiveData.Length, SocketFlags.None, new AsyncCallback(ReceivedData), _client);/密码正确,开始接收消息void ProcessDisconnection()this.lblStatus.Text = 已断开连接!重新监听.;lbConnectLog.Items.Insert(0, 已经断开连接);this.btnDisconnect.Enabled = false; private void txtUserName_TextChanged(object sender, EventArgs e) private void txtPassword_TextChanged(object sender, EventArgs e) private void lblUserName_Click(object sender, EventArgs e) private void gnConnectInfo_Enter(object sender, EventArgs e) private void lbMessage_SelectedIndexChanged(object sender, EventArgs e) private void lbNativeIP_SelectedIndexChanged(object sender, EventArgs e) private void lbConnectLog_SelectedIndexChanged(object sender, EventArgs e) TCP客户端:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Net;using System.Net.Sockets;namespace TCP客户端public partial class TcpClientForm : FormSocket _client;byte _receivedData = new byte1024;public TcpClientForm()InitializeComponent();private void btnConnect_Click(object sender, EventArgs e)this.lblStatus.Text = 连接中.;_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);/建立一个协议为TCP的socketIPEndPoint iep = new IPEndPoint(IPAddress.Parse(this.txtIP.Text), 8000);/设置端口为8000_client.BeginConnect(iep, new AsyncCallback(Connected), _client);/异步调用,开始连接服务端this.btnConnect.Enabled = false;this.btnDisconnect.Enabled = true;private void btnDisconnect_Click(object sender, EventArgs e)_client.Close();this.lblStatus.Text = 连接断开!;this.btnConnect.Enabled = true;this.btnDisconnect.Enabled = false;private void btnSend_Click(object sender, EventArgs e)byte message = Encoding.Default.GetBytes(DateTime.Now.TimeOfDay + : + this.txtMessage.Text);/将文本框里的东西整合成消息txtMessage.Focus();try_client.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(SentData), _client);/开始发送txtMessage.Clear();catchProcessDisconnection();return;void Connected(IAsyncResult iar)_client = (Socket)iar.AsyncState;try_client.EndConnect(iar);/关闭连接请求this.lblStatus.Text = 连接到: + _client.RemoteEndPoint.ToString();_client.BeginReceive(_receivedData, 0, _receivedData.Length, SocketFlags.None, new AsyncCallback(ReceivedData), _client);/异步调用,开始接收消息catchProcessDisconnection();return;void ReceivedData(IAsyncResult iar)Socket remote = (Socket)iar.AsyncState;int recv;tryrecv = remote.EndReceive(iar);catchProcessDisconnection();return;if (recv = 0)_client.Close();ProcessDisconnection();return;string receiveMessage = Encoding.Default.GetString(_receivedData, 0, recv);/将收到的消息处理为字符串this.lbMessage.Items.Insert(0, receiveMessage);/将收到的消息放到消息列表if (receiveMessage.Substring(receiveMessage.LastIndexOf(:) + 1, receiveMessage.Length - (receiveMessage.LastIndexOf(:) + 1) = 请发送用户与密码)byte usernameAndPassword = Encoding.Default.GetBytes(DateTime.Now.TimeOfDay + : + txtUserName.Text + # + txtPassword.Text).ToArray();try_client.BeginSend(usernameAndPassword, 0, usernameAndPassword.Length, SocketFlags.None, new AsyncCallback(SentData), _client);/向服务端发送用户名和密码catchProcessDisconnection();return;/try_client.BeginReceive(_receivedData, 0, _receivedData.Length, SocketFlags.None, new AsyncCallback(ReceivedData), _client);catchProcessDisconnection();return;void SentData(IAsyncResult iar)Socket remote = (Socket)iar.AsyncState;int sent = remote.EndSend(iar);tryremote.BeginReceive(_receivedData, 0, _receivedData.Length, SocketFlags.None, new AsyncCallback(ReceivedData), remote);catchProcessDisconnection();return;void ProcessDisconnection()this.lblStatus.Text = 发送端已经断开连接,或者接收端已经关闭!请重新尝试连接!;this.btnConnect.Enabled = true;btnDisconnect.Enabled = false; private void txtIP_TextChanged(object sender, EventArgs e) UDP发送端:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Net;using System.Net.Sockets;/using System.Threading;namespace UDP发送端public partial class UdpSendForm : Formpublic UdpSendForm()InitializeComponent();private void btnSend_Click(object sender, EventArgs e)/创建UDP网络服务UdpClient SendUdp = new UdpClient();IPAddress remoteIP;/判断IP地址的正确性tryremoteIP = IPAddress.Parse(txtIP.Text)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 汉字的来历课件
- 云南省昆明市2024-2025学年七年级下学期期中考试地理试卷(含答案)
- 广东省湛江市第一中学2024-2025学年第一学期第三次综合素质评价(期末)试卷(含解析)
- 工地协议书范文
- 工厂厂房转让合同(6篇)
- 2024-2025学年广东省广州市番禺区高二(下)期末物理试卷(含答案)
- 《诗经》与楚辞导读知到智慧树答案
- 成都二手房买卖合同(15篇)
- 房地产誓师大会发言稿
- 汉字书法课件模板图
- 建筑公司分包合同管理办法
- 2025至2030苏打水行业发展趋势分析与未来投资战略咨询研究报告
- 2025年秋季学期德育工作计划:向下扎根向上开花
- 2025-2030中国家政服务行业信用体系建设与服务质量监管报告
- 2025年安徽省普通高中学业水平选择性考试(物理)科目高考真题+(答案解析版)
- 2025年成都东部集团有限公司及下属企业招聘考试笔试试卷【附答案】
- 各分项工程质量保证措施
- 国税编制管理办法
- 特种畜禽管理办法
- 消防员心理健康教育课件教学
- 藏族课件模板
评论
0/150
提交评论