C#网编Winform(三)

C#网编Winform(三)

一、TCP/IP层次模型

应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业应用和互联网应用。http协议在应用层运行。

传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP提供传输保证。

网络层(Netwok):网络层协议由一系列协议组成,包括ICMP、IGMP、RIP、OSPF、IP(v4,v6)等。

链路层(Link):又称为物理数据网络接口层,负责报文传输。

二、端口

  • 端口号范围:0-65535,总共能表示65536个数

按端口号可分为3大类

(1)公认端口(WellKnownPorts):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯。


(2)注册端口(RegisteredPorts):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。


(3)动态和/或私有端口(Dynamicand/orPrivatePorts):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口。


  • 通过IP地址确定了网络中的一台电脑后,该电脑上可能提供很多提供服务的应用,每一个应用都对应一个端口。

1、Internet上主机一般运行了多个服务软件 ,同时提供几种服务,每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应用程序)

例如:http 使用80端口, ftp使用21端口 smtp使用25端口

三、Socket一般应用模式(服务器端和客户端)

服务器端的Socket(至少需要两个)
一个负责接收客户端连接请求(但不负责与客户端通信)
另一个当成功接收到客户端的连接便在服务器端产生一个对应的复杂通信的Socket负责和客户端通信

通讯过程服务器端:
01,申请一个socket
02,绑定到一个IP地址和一个端口上
03,开启侦听,等待接收连接
04、服务器端接收到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通信,原监听socket继续监听。负责通信的Socket不能无限创建,创建的数量和操作系统有关。

客户端的Socket
必须指定要连接的服务器地址和端口
通过创建一个Socket对象来初始化一个到服务器端的TCP连接

通讯过程客户端:
01,申请一个socket
02,连接服务器(指明IP地址和端口号)

四.Socket的构造函数

  Public Socket(AddressFamily addressFamily,SocketType  socketType,ProtocolType  protocolTYpe)
  • 参数列表:
    AddressFamily:指定Socket用来解析地址的寻址方案。例如:InterNetWork指示当Socket使用一个IP版本4地址连接
    SocketType:定义要打开的Socket的类型
    Socket类使用ProtocolType枚举向Windows Sockets API通知所请求的协议
  • 端口号:
    1,端口号必须在 1 和 65535之间,最好在1024以后。
    2,要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。

五.Socket常用类与API

  • 相关类:
   IPAddress:包含了一个IP地址
   IPEndPoint:包含了一对IP地址和端口号
  • 方法:
   Socket():创建一个Socket
   Bind():绑定一个本地的IP和端口号(IPEndPoint)
   Listen():让Socket侦听传入的连接吃那个病,并指定侦听队列容量
   Connect():初始化与另一个Socket的连接
   Accept():接收连接并返回一个新的Socket
   Send():输出数据到Socket
   Receive():从Socket中读取数据
   Close():关闭Socket,销毁连接

六.Winform举例

// 服务器
private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }
 
 
private void btnListen_Click(object sender, EventArgs e)
{
	//ip地址
	IPAddress ip = IPAddress.Parse(txtIP.Text);
   // IPAddress ip = IPAddress.Any;
	//端口号
	IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));
	Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
	//创建好socket后,必须告诉socket绑定的IP地址和端口号。
	//让socket监听point
	try
	{
		//socket监听哪个端口
		socket.Bind(point);
		//同一个时间点过来10个客户端,排队
		socket.Listen(10);
		ShowMsg("服务器开始监听");
		Thread thread = new Thread(AcceptInfo);
		thread.IsBackground = true;
		thread.Start(socket);
	}
	catch (Exception ex)
	{              
	   ShowMsg(ex.Message);
	}
}
		
		

//记录通信用的Socket

Dictionary<string,Socket> dic=new Dictionary<string, Socket>();

// private Socket client;

void AcceptInfo(object o)
{
	Socket socket = o as Socket;
	while (true)
	{
		//通信用socket
		try
		{
			//创建通信用的Socket
		  Socket  tSocket = socket.Accept();
		  string point = tSocket.RemoteEndPoint.ToString();

			//IPEndPoint endPoint = (IPEndPoint)client.RemoteEndPoint;

			//string me = Dns.GetHostName();//得到本机名称

			//MessageBox.Show(me);

		 ShowMsg(point + "连接成功!");
		 cboIpPort.Items.Add(point);
		 dic.Add(point, tSocket);
			//接收消息
			Thread th = new Thread(ReceiveMsg);
			th.IsBackground = true;
			th.Start(tSocket);
		}
		catch (Exception ex)
		{
			ShowMsg(ex.Message);
			break;
		}
	}
}

		
//接收消息
void ReceiveMsg(object o)
{
	Socket client = o as Socket;
	while (true)
	{
		//接收客户端发送过来的数据
		try
		{
			//定义byte数组存放从客户端接收过来的数据
			byte[] buffer = new byte[1024 * 1024];
			//将接收过来的数据放到buffer中,并返回实际接受数据的长度
			int n = client.Receive(buffer);
			//将字节转换成字符串
			string words = Encoding.UTF8.GetString(buffer, 0, n);
			ShowMsg(client.RemoteEndPoint.ToString() + ":" + words);
		}
		catch (Exception ex)

		{
		   ShowMsg(ex.Message);
			break;
		}
	}
}
		
		
		
 
void ShowMsg(string msg)
{
	txtLog.AppendText(msg+"
");
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
	//主窗体关闭时关闭子线程

}		

//给客户端发送消息
private void btnSend_Click(object sender, EventArgs e)
{
	try
	{
		ShowMsg(txtMsg.Text);
		string ip = cboIpPort.Text;
		byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);
		dic[ip].Send(buffer);
		// client.Send(buffer);
	}
	catch (Exception ex)
	{
	   ShowMsg(ex.Message);
	}
}
//客户端
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

private void btnConnection_Click(object sender, EventArgs e)
{
	//连接到的目标IP
	IPAddress ip = IPAddress.Parse(txtIP.Text);
	//IPAddress ip = IPAddress.Any;
	//连接到目标IP的哪个应用(端口号!)
	IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));
	try
	{
		//连接到服务器
		client.Connect(point);
		ShowMsg("连接成功");
		ShowMsg("服务器" + client.RemoteEndPoint.ToString());
		ShowMsg("客户端:" + client.LocalEndPoint.ToString());
		//连接成功后,就可以接收服务器发送的信息了
		Thread th=new Thread(ReceiveMsg);
		th.IsBackground = true;
		th.Start();
	}
	catch (Exception ex)
	{
		ShowMsg(ex.Message);
	}
}

//接收服务器的消息
void ReceiveMsg()
{
	while (true)
	{
		try
		{
			byte[] buffer = new byte[1024 * 1024];
			int n = client.Receive(buffer);
			string s = Encoding.UTF8.GetString(buffer, 0, n);
			ShowMsg(client.RemoteEndPoint.ToString() + ":" + s);
		}
		catch (Exception ex)
		{
			ShowMsg(ex.Message);
			break;
		}
	}
}


void ShowMsg(string msg)

{
	txtInfo.AppendText(msg+"
");
}

private void btnSend_Click(object sender, EventArgs e)

{
	//客户端给服务器发消息

	if (client!=null)
	{
		try
		{
			ShowMsg(txtMsg.Text);
			byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);
			client.Send(buffer);
		}
		catch (Exception ex)

		{
		   ShowMsg(ex.Message);
		}
	}
}

private void ClientForm_Load(object sender, EventArgs e)
{
	Control.CheckForIllegalCrossThreadCalls = false;
}

Winform_UDP

https://blog.csdn.net/panjinliang066333/article/details/55107387

https://download.csdn.net/download/soupman0419/6414603

https://blog.csdn.net/shi_shu_song/article/details/70048865

https://blog.csdn.net/dqs78833488/article/details/51331341

原文地址:https://www.cnblogs.com/retry/p/9353946.html