1.目的:实现客户端向服务器发送数据

  原理:



2.建立两个控制台应用,一个为服务器,用于接收数据。一个为客户端,用于发送数据。

  关键类与对应方法:

  1)类IPEndPoint:

  1.是抽象类EndPoint的实现类

  2.Socket对象的RemoteEndPoint、 LocalEndPoint都是这个类型

  3.属性Address: 使用IPv4表示的地址

  4.属性Port:使用int表示的端口

  2)类Socket:

  这个类即可以用于作服务器端的开发,又可以作客户端的开发

  构造方法:

  参数 AddressFamily:指定使用IPv4的地址InterNetwork

  参数SocketType:指定使用流式传输Stream

  参数ProtocolType:指定协议类型Tcp

  1.方法Bind()E 绑定IP与端口,这样就成为了服务器,可以监听指定IP的特定端口

  2.方法Listen(); 置于监听状态,参数是最大的挂起数

  3.方法Accept(): 接收客户端连接,返回Socket对象, 这个方法会阻塞当前线程,建议开启新线程执行些方法,结合尾递归,这样就可以接收多个客户端

  4.方法Receive():
接收客户端发送过来的消息,以字节为单位进行操作,此方法会阻塞当前线程,建议开启新线程执行此方法,结合尾递归,就可以持续接收多条信息

  5. 方法Send(): 发送消息,以字节为单位

3.具体实现

     其他内容不做过多解释了,备注做的超详细,应该只有笨笨的人才写这么多备注吧。。

  1.服务器

     主函数:
using System; using System.Collections.Generic; using System.Linq; using
System.Text;using System.Threading.Tasks; namespace ServerTest { class Program {
static void Main(string[] args) { // 调用构造函数,使用Start方法 ServerControl server = new
ServerControl(); server.Start(); Console.ReadKey(); } } }
     ServerControl类:
using System; using System.Collections.Generic; using System.Linq; using
System.Net;using System.Net.Sockets; using System.Text; using System.Threading;
using System.Threading.Tasks; namespace ServerTest { public class ServerControl
{// 声明变量(使用Socket需using System.Net.Sockets;) private Socket serverSocket; //
自定义有参构造方法(IP地址,流程传输方式,TCP协议) public ServerControl() { serverSocket = new
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); }//
创建启动方法(IPEndPoint用于指定地址及端口初始化,需using System.Net;) public void Start() { // 服务器启动
// 绑定IP地址(为任意IP)与端口(设置为12345) serverSocket.Bind(new IPEndPoint(IPAddress.Any,
12345)); serverSocket.Listen(10); Console.WriteLine("服务器启动成功"); //
开启线程:目的实现服务器和客户端一对多连接 Thread threadAccept = new Thread(Accept);
threadAccept.IsBackground= true; threadAccept.Start(); } // Accept方法测试:接收客户端连接
private void Accept() { // 接收客户端方法,会挂起当前线程(.RemoteEndPoint表示远程地址) Socket client
= serverSocket.Accept(); IPEndPoint point = client.RemoteEndPoint as
IPEndPoint; Console.WriteLine(point.Address+ "[" + point.Port + "] 连接成功!"); //
开启一个新线程线程,实现消息多次接收 Thread threadReceive = new Thread(Receive);
threadReceive.IsBackground= true; threadReceive.Start(client); // 尾递归
Accept(); }// Receive方法的使用测试 // 接收客户端发送过来的消息,以字节为单位进行操作 //
该方法会阻塞当前线程,所以适合开启新的线程使用该方法//
Accept()中将Receive作为线程传递对象,所以要注意一点,使用线程传递对象只能是object类型的!! private void Receive(
object obj) { // 将object类型强行转换成socket Socket client = obj as Socket; IPEndPoint
point= client.RemoteEndPoint as IPEndPoint; // 此处的异常抛出主要针对客户端异常的问题 //
比如,客户端关闭或者连接中断// 程序会停留在int msgLen = client.Receive(msg);这段代码,而导致无法继续往下走 try {
byte[] msg = new byte[1024]; //
实际接收到字节数组长度,该方法会阻塞当前线程,即(client.Receive(msg)开始挂起)// 同时,这里还是尾递归挂起处 int msgLen =
client.Receive(msg);// 将msg装换成字符串 Console.WriteLine(point.Address + "[" +
point.Port +"]:" + Encoding.UTF8.GetString(msg, 0, msgLen)); //
此处实现服务器自动向客户端返回一条消息// 因为Send发送信息是以字节为单位发送的 //
所以下面(Encoding.UTF8.GetString(msg,0,msgLen)+" yes.boy")这一块是把这一部分均搞成string//
后使用Encoding.UTF8.GetBytes统一转化成字节传递//
这里呢,已经实现服务器向客户端发送消息了,客户端只需要receive一下,格式一转就可视化了
client.Send(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(msg,0,msgLen)+"
yes.boy")); // 尾递归实现多条消息的接收;和while同理。 Receive(client); } catch {
Console.WriteLine(point.Address+ "[" + point.Port + "]积极断开"); } } } }
2.客户端:

   主函数:
client.Connect("127.0.0.1",12345);
修改IP可实现不同计算机之间的连接。 using System; using System.Collections.Generic; using
System.Linq;using System.Text; using System.Threading.Tasks; namespace
ClientTest {class Program { static void Main(string[] args) { // 调用构造函数
ClientControl client =new ClientControl(); // 输入本机IP与端口号 client.Connect("
127.0.0.1",12345); // 提示操作方法 Console.WriteLine("请输入发送至服务器的内容或者输入quit退出"); //
输入内容 string msg = Console.ReadLine(); // 非退出情况下操作方式,使用while可以持续不断的接收用户输入 while
(msg !="quit") { client.Send(msg); msg = Console.ReadLine(); }
Console.ReadKey(); } } }
   ClientControl类:
using System; using System.Collections.Generic; using System.Linq; using
System.Net.Sockets;using System.Text; using System.Threading; using
System.Threading.Tasks;namespace ClientTest { public class ClientControl { //
声明变量 private Socket clientSocket; // 自定义有参构造方法((IP地址,流程传输方式,TCP协议)) public
ClientControl() { clientSocket= new
Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); }//
创建通过IP与端口号连接的方法 public void Connect(string ip,int port) {
clientSocket.Connect(ip, port); Console.WriteLine("连接服务器成功"); // 客户端接收服务器消息的线程
Thread threadReceive =new Thread(Receive); threadReceive.IsBackground = true;
threadReceive.Start(); }// 用于测试服务器向客户端返回一条消息 private void Receive() { while(true
) {try { // 用于接收服务器的回复信息 byte[] msg = new byte[1024]; int msgLen =
clientSocket.Receive(msg); Console.WriteLine("服务器:"+Encoding.UTF8.GetString(msg,
0,msgLen)); } // 异常处理方法 catch { Console.WriteLine("服务器积极拒绝!!"); // 退出while循环
break; } } } // Send方法测试:即发送消息,以字节为单位 public void Send(string msg) { //
将字符创传化为字节数组 clientSocket.Send(Encoding.UTF8.GetBytes(msg)); } } }
4.实现

本地连接:IP为127.0.0.1



远程连接:因为我只有一台电脑,所以用腾讯云服务器作为我的服务器,我本地的PC作为客户端,实现连接。

1.修改客户端主程序里面的IP为我的腾讯云IP



2.使用远程桌面连接



3.连接成功


友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信