一.Socket、TCP、UDP
1. Socket
我们知道两个进程如果需要进行通讯最基本的一个前提能能够唯一的标示一个进程,在本地进程通讯中我们可以使用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很大,这时候我们需要另辟它径了,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程。
能够唯一标示网络中的进程后,它们就可以利用socket进行通信了,什么是socket呢?我们经常把socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。
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 是User Datagram Protocol的简称, 中文名是用户数据包协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768 是UDP的正式规范。UDP在IP报文的协议号是17。
UDP协议与TCP协议一样用于处理数据包,在OSI模型中,两者都位于传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但即使在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。 UDP编程的服务器端一般步骤: 1.创建一个socket,用函数socket() 2.绑定IP地址、端口等信息到socket上,用函数bind() 3.循环接收数据,用函数recvfrom() 4.关闭网络连接 UDP编程的客户端一般步骤: 1.创建一个socket,用函数socket() 2.设置对方的IP地址和端口等属性 3.发送数据,用函数sendto() 4.关闭网络连接
二、UDP套接字发送信息
- 显示信息
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Send1
{
class Program
{
static void Main(string[] args)
{
for(int i = 0; i < 50; i++)
{
Console.WriteLine("hello cqjtu!重交物联2019级");
}
System.Console.ReadLine();
}
}
}
运行结果:
2. 实现UDP套接字发送信息
服务端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Send1
{
class MyServer
{
static void Main()
{
int result;
string str = "第50行:hello cqjtu!重交物联2019级";
UdpClient client = new UdpClient(11000);
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();
}
}
}
客户端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Send1_C
{
class Program
{
static void Main()
{
Console.WriteLine("按下任意按键开始发送...");
Console.ReadKey();
int m;
UdpClient client = new UdpClient();
IPAddress remoteIP = IPAddress.Parse("127.0.0.1");
int remotePort = 11000;
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();
}
}
}
服务端运行:
3. Wireshark抓包与分析
利用Wireshark抓包可以发现抓取了20个包: 随机选取一个包,可以发现这条包的信息是第30行:hello cqjtu!重交物联2019级
三、TCP使用窗口程序发送信息
1.编写代码
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 WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public 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.60.202.32";
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 = "";
}
}
}
2. 服务端编写
创建一个新的控制台程序,在main函数中编写如下代码:
static void Main(string[] args)
{
int i = 0;
int port = 2000;
string host = "127.0.0.1";
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);
}
}
}
在客户端和服务端都编写好以后,运行代码: 客户端:
四、总结
学会了如何使用套接字,更加熟悉了tcp和ucp
五、参考
https://blog.csdn.net/weixin_46628481/article/details/121388939 https://blog.csdn.net/ssj925319/article/details/109336123
|