一、UDP介绍
这部分总结来源于:HarrietLH C#利用套接字实现数据发送
1.Socket
套接字是支持TCP/IP协议的网络通信的基本操作单元。可以将套接字看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面。 套接字的工作原理: 通过互联网进行通信,至少需要一对套接字,其中一个运行于客户机端,称之为ClientSocket,另一个运行于服务器端,称之为ServerSocket。 套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
2.TCP
TCP协议提供的是端到端服务。TCP协议所提供的端到端的服务是保证信息一定能够到达目的地址。它是一种面向连接的协议。 TCP编程的服务器端一般步骤 ①创建一个socket,用函数socket() ②绑定IP地址、端口等信息到socket上,用函数bind() ③开启监听,用函数listen() ④接收客户端上来的连接,用函数accept() ⑤收发数据,用函数send()和recv(),或者read()和write() ⑥关闭网络连接; ⑦关闭监听; TCP编程的客户端一般步骤 ①创建一个socket,用函数socket() ②设置要连接的对方的IP地址和端口等属性 ③连接服务器,用函数connect() ④收发数据,用函数send()和recv(),或者read()和write() ⑤关闭网络连接
3.UDP
UDP协议提供了一种不同于TCP协议的端到端服务。UDP协议所提供的端到端传输服务是尽力而为(best-effort)的,即UDP套接字将尽可能地传送信息,但并不保证信息一定能成功到达目的地址,而且信息到达的顺序与其发送顺序不一定一致。 UDP编程的服务器端一般步骤 ①创建一个socket,用函数socket() ②绑定IP地址、端口等信息到socket上,用函数bind() ③循环接收数据,用函数recvfrom() ④关闭网络连接 UDP编程的客户端一般步骤 ①创建一个socket,用函数socket() ②设置对方的IP地址和端口等属性 ③发送数据,用函数sendto() ④关闭网络连接
通过两种协议的介绍,可以看出对于UDP协议要比TCP简单一些。但是,UDP不能够保证数据传输一定到达目的地址。
二、控制台程序使用 UDP 通信
任务:用C#、Java或python编写一个命令行/控制台的简单hello world程序,实现如下功能:在屏幕上连续输出50行“hello cqjtu!重交物联2019级”;同时打开一个网络UDP 套接字,向另一台室友电脑发送这50行消息。
1.控制台输出hello world
①创建新项目 选择控制台应用(.NET Framework),然后下一步
②添加代码 创建好项目,添加如下代码
for (int i = 0; i < 50; i++)
{
Console.WriteLine("第{0}行:hello cqjtu!重交物联2019级", (i + 1));
}
System.Console.ReadKey();
③运行编译
2.使用UDP在室友电脑输出hello world
我们准备在自己电脑上编写客户端代码,在室友的电脑上编写服务端代码,以此来实现两台电脑通信
①客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Client
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("按下任意按键开始发送...");
Console.ReadKey();
int m;
UdpClient client = new UdpClient();
IPAddress remoteIP = IPAddress.Parse("10.160.184.45");
int remotePort = 1000;
IPEndPoint remotePoint = new IPEndPoint(remoteIP, remotePort);
for (int i = 0; i < 50; i++)
{
string sendString = null;
sendString += "第";
m = i + 1;
sendString += m.ToString();
sendString += "行:hello cqjtu!重交物联2019级";
byte[] sendData = null;
sendData = Encoding.Default.GetBytes(sendString);
client.Send(sendData, sendData.Length, remotePoint);
}
client.Close();
Console.WriteLine("");
Console.WriteLine("数据发送成功,按任意键退出...");
System.Console.ReadKey();
}
}
}
代码流程:
- ①首先显示提示信息,等待使用人员操作;
- ②做好连接准备,如:设置IP、端口号等;
- ③ for 循环发送数据;
- ④关闭端口;
- ⑤显示提示信息,等待用户确认退出。
其中这里的IP是我室友的IP地址,因为要将室友的电脑作为我的服务器
IPAddress remoteIP = IPAddress.Parse("10.160.184.45");
②服务端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Server
{
class Program
{
static void Main(string[] args)
{
int result;
string str = "第50行:hello cqjtu!重交物联2019级";
UdpClient client = new UdpClient(1000);
string receiveString = null;
byte[] receiveData = null;
IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any, 0);
Console.WriteLine("正在准备接收数据...");
while (true)
{
receiveData = client.Receive(ref remotePoint);
receiveString = Encoding.Default.GetString(receiveData);
Console.WriteLine(receiveString);
result = String.Compare(receiveString, str);
if (result == 0)
{
break;
}
}
client.Close();
Console.WriteLine("");
Console.WriteLine("数据接收完毕,按任意键退出...");
System.Console.ReadKey();
}
}
}
代码流程:
- ①做好连接准备,并设置结束标志;
- ②循环接收数据;
- ③关闭连接;
- ④显示提示信息,等待用户确定退出。
③编译结果 客户端: 服务端:
3.利用Wireshark抓包分析
打开Wireshark之后在这里输入过滤条件ip.dst==10.160.184.45 这里的过滤条件是显示目标地址为10.160.184.45的数据包列表,也就是我室友的IP
可以从上图看出来已经抓到了我向目标IP发送的包,选择其中一个包 可以看到我发送的内容
三、Form窗口程序使用 TCP 通信
任务:用VS2017/2019 的C#编写一个简单的Form窗口程序,有一个文本框 textEdit和一个发送按钮button,运行程序后,可以在文本框里输入文字,如“hello cqjtu!重交物联2019级”,点击button,将这些文字发送给室友电脑,采用UDP套接字;
1.创建项目
新建项目选择Windows 窗体应用 选择好项目文件路径,然后创建项目
2.设计图形界面
借助工具箱完成各个控件的设置(我们这里简单设置了两个Texbox和一个Button)
3.代码编写
双击发送按钮跳转到对应的代码
在 button1_Click 函数内复制粘贴如下代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
string str = "The current time: ";
str += DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
textBox2.AppendText(str + Environment.NewLine);
int port = 2000;
string host = "10.61.54.150";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
str = "Connect to server...";
textBox2.AppendText(str + Environment.NewLine);
c.Connect(ipe);
string sendStr = textBox1.Text;
str = "The message content: " + sendStr;
textBox2.AppendText(str + Environment.NewLine);
byte[] bs = Encoding.UTF8.GetBytes(sendStr);
str = "Send the message to the server...";
textBox2.AppendText(str + Environment.NewLine);
c.Send(bs, bs.Length, 0);
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
bytes = c.Receive(recvBytes, recvBytes.Length, 0);
recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
str = "The server feedback: " + recvStr;
textBox2.AppendText(str + Environment.NewLine);
c.Close();
}
catch (ArgumentNullException f)
{
string str = "ArgumentNullException: " + f.ToString();
textBox2.AppendText(str + Environment.NewLine);
}
catch (SocketException f)
{
string str = "ArgumentNullException: " + f.ToString();
textBox2.AppendText(str + Environment.NewLine);
}
textBox2.AppendText("" + Environment.NewLine);
textBox1.Text = "";
}
}
}
然后在我室友的电脑上创建一个控制台程序 代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
int i = 0;
int port = 2000;
string host = "10.61.54.150";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Bind(ipe);
while (true)
{
i++;
try
{
Console.Write("Perform operations {0} :",i);
Console.WriteLine("\t-----------------------------------------------");
s.Listen(0);
Console.WriteLine("1. Wait for connect...");
Socket temp = s.Accept();
Console.WriteLine("2. Get a connect");
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
bytes = temp.Receive(recvBytes, recvBytes.Length, 0);
recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
Console.WriteLine("3. Server Get Message:{0}", recvStr);
string sendStr = "Ok!Client send message sucessful!";
byte[] bs = Encoding.UTF8.GetBytes(sendStr);
temp.Send(bs, bs.Length, 0);
temp.Close();
Console.WriteLine("4. Completed...");
Console.WriteLine("-----------------------------------------------------------------------");
Console.WriteLine("");
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
}
}
}
}
4.程序运行
客户端:
服务端:
5.利用Wireshark抓包分析
打开Wireshark之后在这里输入过滤条件ip.dst==10.61.54.150 这里的过滤条件是显示目标地址为10.160.184.45的数据包列表,也就是我室友的IP
抓到TCP的包,打开查看发送的内容
四、参考文献
1.HarrietLH C#利用套接字实现数据发送 2.可乐有点好喝 C#使用TCP/UDP协议通信并用Wireshark抓包分析数据
|