文章目录
前言
本文将讲解如何用C#进行网络编程,如何进行客户端与服务器之间的通信,看完本文你将学会最基本的客户端与服务器之间的通信
一、TCP/IP模型
TCP/IP并非指TCP和IP两种协议,而是指一系列网络通信的协议簇,模型有5层和7层两种,7层模型多添加了表示层和会话层,下面展示5层网络模型,如下所示:
二、端口(port)
端口的范围为0~65535,可分为3大类,公认服务,注册服务,动态或私有端口,一般来说一个服务对应一个端口,我们通过IP地址找到对应的主机,之后再通过对应的端口找到对应的服务器并与之进行通信.
三、套接字(Socket)
套接字主要分为两种,分别是流式套接字(面向连接,TCP)和数据报套接字(无连接,UDP).服务端的套接字至少有2个,一个负责接收客户端的连接(不负责与客户端进行通信),当检测到客户端的连接时,便通过线程产生一个新的更为复杂的套接字与客户端进行通信,如下所示:
四、客户端套接字(Socket)
在进行连接服务器时必须指定服务器的地址(确定主机)和端口(确定主机上的服务),如下图所示
五、C#网络编程
Socket构造函数 public Socket(AddressFamily,SocketType,protocolType)
AddressFamily:指定socket用来解析地址的寻址方案,如指定用IPV4版本连接(InterNetWork),
SocketType:定义打开Socket的类型,
ProtocolType:指定协议,如使用TCP或UPD等
IPAddress:包含一个IP地址,可用以将一个字符串的IP地址进行转化
IPEndPoint:包含IP地址以及端口(IP and port)
对于服务器的Socket来说,我们必须绑定其IP地址以及端口
六、客户端与服务器代码编写(客户端与服务器需在不同的工程中)
1.客户端代码
代码如下(示例):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace Client
{
class Client
{
private static byte[] result = new byte[1024];
private Socket clientSocket;
//表示是否连上服务器
public bool isConnect = false;
public Client()
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
/// <summary>
/// 连接指定IP地址和端口的服务器
/// </summary>
/// <param name="ip">服务器IP地址</param>
/// <param name="port">服务器端口名称</param>
public void ConnectServer(string ipStr, int port)
{
IPAddress ip = IPAddress.Parse(ipStr);
IPEndPoint ip_end_point = new IPEndPoint(ip, port);
try
{
clientSocket.Connect(ip_end_point);
isConnect = true;
Console.WriteLine("服务器连接成功.....");
}
catch
{
isConnect = false;
Console.WriteLine("服务器连接失败.....");
return;
}
//接收服务器发送的数据
int receiveLength = clientSocket.Receive(result);
Console.WriteLine( Encoding.UTF8.GetString(result));
}
/// <summary>
/// 发送数据给服务器
/// </summary>
/// <param name="data">向服务器发送的数据</param>
public void SendMessage(string data)
{
if (isConnect)
{
try
{
clientSocket.Send(Encoding.UTF8.GetBytes(data));
}
catch
{
isConnect = false;
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
}
}
}
2.服务器代码
代码如下(示例):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//引入所需的命名空间
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace SocketTest
{
class Server
{
private static byte[] result = new byte[1024];
//服务器端口
private const int port = 8088;
//ip地址字符串,127.0.0.1为本机
private static string ipStr = "127.0.0.1";
private static Socket serverSocket;
static void Main(string[] args)
{
//字符串IP地址转化成IP地址
IPAddress ip = IPAddress.Parse(ipStr);
IPEndPoint ip_end_point = new IPEndPoint(ip, port);
//创建服务器Socket对象,并设置相关属性
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//为套接字绑定IP和端口
serverSocket.Bind(ip_end_point);
//设置最大长度连接请求队列
serverSocket.Listen(10);
//Console.WriteLine("启动监听成功{0}", serverSocket.LocalEndPoint.ToString());
Thread thread = new Thread(ClientConnectListen);
thread.Start();
Console.WriteLine();
}
/// <summary>
/// 客户端连接请求监听
/// </summary>
private static void ClientConnectListen()
{
while (true)
{
Console.WriteLine("服务器启动中.......");
//为新的客户端连接创建一个Socket对象
Socket clientSocket = serverSocket.Accept();
Console.WriteLine("客户端{0}成功连接", clientSocket.RemoteEndPoint.ToString());
//向连接的客户端送连接成功的数据
clientSocket.Send(System.Text.Encoding.UTF8.GetBytes("服务器:hello"));
//为每个客户端连接创建一个线程来接收客户端发来的消息
Thread thrend = new Thread(ReceiveMessage);
thrend.Start(clientSocket);
}
}
/// <summary>
/// 接收指定客户端的消息
/// </summary>
/// <param name="clientSocket"></param>
private static void ReceiveMessage(object clientSocket)
{
//return null;
Socket mClientSocket = (Socket)clientSocket;
while (true)
{
int receiveNumber = mClientSocket.Receive(result);
//Console.WriteLine("客户端接收{0}消息,长度为{1}", mClientSocket.RemoteEndPoint.ToString(), receiveNumber);
Console.WriteLine(Encoding.UTF8.GetString(result));
}
}
}
}
3.测试代码
代码如下(示例):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client
{
class test
{
public static void Main(string[] args)
{
Client client = new Client();
client.ConnectServer("127.0.0.1", 8088);
client.SendMessage("客户端:hello!");
while (true)
{
}
}
}
}
该处使用的url网络请求的数据。
七 、实现效果展示
服务器启动:
启动测试:
网络编程其实并不高深,无非就是客户端与服务器之间的简单通信而已,当您深入理解其中的原理时,一切都是简单的,当然这里我们只是进行简单的运用.