第一章、C#最简单的控制台网络通信&C#最简单的控制台socket通信&两个控制台聊天

C#网络通信系列学习笔记



前言

网络通信是很多码农入职的第一课,也是毕业设计、课程设计上使用的重灾区,可以说不会网络通信的码农不是一个好码农。
通过这篇文章,你将学习如何使用C#Socket库来进行通信。ok,我们先从最简单的控制台开始。


一、Socket是什么?

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
Socket的英文原义是“孔”或“插座”。作为BSD UNIX的 进程通信机制,取后一种意思。通常也称作" 套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的 主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。——C#Socket通信原理(基础篇)

也就是说

  1. 网络上的两台主机要想完成通信需要两边都做好准备,这个准备工作可以由Socket来完成
  2. 一个socket需要占用一个本地计算机的端口
  3. 一台计算机上的不同软件可以与不同的远程计算机通信,他们之间是互不干扰的
  4. 一台计算机上的多个软件可能在与远程同一台计算机进行通信,但是它们用的端口是不同的,也就是两台主机之间可能存在着多个连接,尽管连接的对象都是一样的
  5. 我可以客户端和服务端都在一台主机上,自己跟自己玩~

另外,网络通信是分为客户端模式和服务器模式的
客户端模式:我需要连接到一个指定的IP地址和端口号,因此我必须知道对方的IP地址和端口号
服务器模式:我不知道谁会连接我,因此我绑定一个固定端口随时监听它,等待客户端的连接请求。

二、最简单的控制台通信

1.客户端

代码如下(示例):

using System;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //建立一个socket对象需要指定socket类型、协议类型等参数
            //这里第一个参数使用IPv4版本的地址,第二个参数指可靠稳定的字节流socket,第三个参数是采用TCP\协议
            Socket ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress ServerIP = IPAddress.Parse("127.0.0.1");//将ip地址字符串转化为ip地址对象,这里以本地作为服务器
            //在Internet中,TCP/IP使用一个网络地址和一个服务端口号来唯一标识设备。网络地址标识网络上的特定设备;
            //端口号标识要连接到的该设备上的特定服务。网络地址和服务端口的组合称为终结点,
            //在.NET框架中正是由EndPoint类表示这个终结点,它提供表示网络资源或服务的抽象,用以标志网络地址等信息
            IPEndPoint endPoint = new IPEndPoint(ServerIP, 20000);//端口号可以自己设置,不要与其他程序冲突,与服务端保持一致就可以
            ClientSocket.Connect(endPoint);//连接到这个终结点,这里要注意如果连接不上是会报错的哦
            string MyMsg = "我要发送的数据";
            byte[] MsgByteArray = Encoding.UTF8.GetBytes(MyMsg);//文字信息是不能直接发送的,需要先转化为字节流
            int SendNum = ClientSocket.Send(MsgByteArray);//这里使用最简单的一种重载,直接发送字节数组
            if (SendNum <= 0)
                Console.WriteLine("发送失败");
            else
                Console.WriteLine("发送成功");
            ClientSocket.Blocking = true;//设置为阻塞模式,否则可能接收不到数据
            byte[] ReceiveMsgByteArray = new byte[1024];
            ClientSocket.Receive(ReceiveMsgByteArray);//接收返回的信息
            Console.WriteLine(Encoding.UTF8.GetString(ReceiveMsgByteArray));//将收到的字节流转换回字符串并打印
            Console.ReadLine();//这里读取一行输入,防止程序执行完闪退
            ClientSocket.Close();//关闭socket连接
        }
    }
}

在这个例子中我们只让它发送一条消息并接收一条消息就可以了,当然现在还是没办法胜任这个任务的,因为根本打不开连接呀~
接下来我们在写一个服务端的控制台程序来跟它互动

2.服务端

代码如下(示例):

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //IPAddress kehuip = IPAddress.Parse("0.0.0.0");
            IPAddress ClientIP = IPAddress.Any;//允许哪个地址连接我,这个值表示任意,与上面的表示形式相同
            Socket socketwatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint endPoint = new IPEndPoint(ClientIP, 20000);//监听20000端口,客户端连接的时候就需要连接这个端口号
            socketwatch.Bind(endPoint);//绑定这个终结点
            socketwatch.Listen(3);//开始监听,参数表示最大允许几台主机连接我
            Console.WriteLine("开始监听 端口号:20000 \r\n");
            Socket ClientSocket = socketwatch.Accept();//如果有客户端连接,就会返回这个客户端的sockeet对象
            ClientSocket.Blocking = true;
            byte[] ReceiveMsgByteArray = new byte[1024];
            ClientSocket.Receive(ReceiveMsgByteArray);//接收返回的信息
            Console.WriteLine(Encoding.UTF8.GetString(ReceiveMsgByteArray));//将收到的字节流转换回字符串并打印
            ClientSocket.Send(Encoding.UTF8.GetBytes("我收到了你的消息"));//礼尚往来,给客户端回一句
            Console.ReadLine();//这里读取一行输入,防止程序执行完闪退
            ClientSocket.Close();//关闭socket连接
        }
    }
}

3.执行

先运行服务端的控制台程序

在跑上客户端控制台
在这里插入图片描述
啪的一下很快啊,都没反应过来两边就都收到了并且运行结束了,我们给它加个延时直观一点。
在这里插入图片描述
服务端加上这两行断点处的代码
在这里插入图片描述
客户端加上这两行,按上述步骤再次执行
在这里插入图片描述

总结

以上就是最简单的C#控制台网络通信的实例了,在下一章中,将 会在这个控制台的基础上修改为多次发送多次接收
### 回答1: 您好,如果您想使用C语言进行编程,您可以选择下载安装C语言的编译器,比如GCC或者Clang等。这些编译器都是免费的,并且可以在Windows、Linux和MacOS等操作系统上运行。安装好编译器后,您就可以开始编写C语言代码并进行编译了。如果您需要学习C语言的知识,您可以查找一些在线的C语言教程或者参考一些经典的C语言书籍,比如《C程序设计语言》等。 ### 回答2: 编写一个打印“Hello, World!”的C程序。 在C语言中,要打印一段文字,可以使用标准库函数printf来实现。printf函数用于格式化输出,可以输出各种类型的数据。 下面是一个简单的例子: ```c #include <stdio.h> int main() { printf("Hello, World!\n"); return 0; } ``` 这是一个最基本的C程序结构。首先,我们在代码前面包含头文件stdio.h,这个头文件是标准输入输出函数的声明文件。 然后,在main函数中,我们调用printf函数来输出字符串"Hello, World!",并在字符串后面加上换行符"\n",以让输出结果换行显示。 最后,我们返回0作为程序的退出状态码,表示程序正常运行结束。 当你将这段代码保存为一个.c文件,并使用C编译器进行编译,运行可执行文件时,你将看到控制台输出了"Hello, World!"。这是C语言入门非常经典的一个例子。 希望以上回答对你有所帮助,如果有任何其他问题,请随时提问。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jumul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值