惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
罗磊的独立博客
小众软件
小众软件
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
博客园_首页
N
Netflix TechBlog - Medium
B
Blog
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
Blog — PlanetScale
Blog — PlanetScale
L
LangChain Blog
F
Fortinet All Blogs
The GitHub Blog
The GitHub Blog
Stack Overflow Blog
Stack Overflow Blog
C
Check Point Blog
Last Week in AI
Last Week in AI
Jina AI
Jina AI
V
V2EX
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
博客园 - 【当耐特】

zodream梦想开源/个人编程日记

文件解析笔记-zodream梦想开源/个人编程日记 密码本开发笔记之读写与保存-zodream梦想开源/个人编程日记 SkiaSharp 把 pixel byte[] 转成 SKBitmap-zodream梦想开源/个人编程日记 nas 使用 Docker 安装 gogs-zodream梦想开源/个人编程日记 复制 android 手机中的文件到电脑-zodream梦想开源/个人编程日记 周报:寻找优质的周刊-zodream梦想开源/个人编程日记 开发日志:对Markdown的代码块新增引用来源支持-zodream梦想开源/个人编程日记 周报:怎么写技术类的教程文章-zodream梦想开源/个人编程日记 css display:flex 布局尺寸超出问题-zodream梦想开源/个人编程日记 周报:SEO优化的思考-zodream梦想开源/个人编程日记 Edge 浏览器不适用 Edge Image Viewer 打开图片 -zodream梦想开源/个人编程日记 SEO 学习笔记(一) 内容来源-zodream梦想开源/个人编程日记 PHP 实现双因素身份认证(2FA)-zodream梦想开源/个人编程日记 WPF MVVM 获取List 多选数据-zodream梦想开源/个人编程日记 Burp Suite 抓包-zodream梦想开源/个人编程日记 使用 indexnow 注意事项-zodream梦想开源/个人编程日记 Godot 使用字体图标 例如: Iconfont、FontAwesome-zodream梦想开源/个人编程日记 angular 15 对指定页面进行访问限制-zodream梦想开源/个人编程日记 CSS 使用 column-count 实现瀑布流出现内容分割的解决办法-zodream梦想开源/个人编程日记 input 确认按键事件在手机端不生效-zodream梦想开源/个人编程日记 Maui开发中Windows应用开启管理员权限-zodream梦想开源/个人编程日记 Maui 中自定义控件-zodream梦想开源/个人编程日记 angular 14 使用 ng-template 实现tree 结构显示-zodream梦想开源/个人编程日记 c# 动态安装和卸载dll-zodream梦想开源/个人编程日记 慎用 CompositionTarget.Rendering-zodream梦想开源/个人编程日记 c# 重写 c++ 程序笔记:数据初始化-zodream梦想开源/个人编程日记 源码编译 aseprite-zodream梦想开源/个人编程日记 记录一下字符串分隔split各语言之间的不同-zodream梦想开源/个人编程日记 c# Gzip解码无头内容-zodream梦想开源/个人编程日记 Windows 10 查看内存占用-zodream梦想开源/个人编程日记
C# 使用socket 进行通讯-zodream梦想开源/个人编程日记
zodream · 2023-03-04 · via zodream梦想开源/个人编程日记

基于UDP

发送

// 本机ip和端口
var localIp = new IPEndPoint(IPAddress.Parse(ip), port);
var udpSocket = new Socket(serverIp.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
udpSocket.Bind(localIp);


public void Send(string ip, int port, byte[] buffer)
{
    var remote = new IPEndPoint(IPAddress.Parse(ip), port);
    udpSocket.SendTo(buffer, remote);
}

1234567891011

数据必须一次发送,不能分段发送,不然顺序会混乱,数据大小也要注意,因为接收时只能接收一次,多出的数据就会接收不到了

接收

// 本机ip和端口
var localIp = new IPEndPoint(IPAddress.Parse(ip), port);
var udpSocket = new Socket(serverIp.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
udpSocket.Bind(localIp);


var buffer = new byte[65536];
EndPoint sendIp = new IPEndPoint(IPAddress.Any, port);
var length = udpSocket.ReceiveFrom(buffer, Constants.UDP_BUFFER_SIZE,
    SocketFlags.None, ref sendIp);

1234567891011

TCP

发送

var remoteIp = new IPEndPoint(IPAddress.Parse(ip), port);
var socket = new Socket(clientIp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(remoteIp);

var buffer = new byte[8];

socket.Send(buffer);

private void Send(byte[] buffer, int length)
{
    var index = 0;
    while (index < length)
    {
        var size = socket.Send(buffer, index, length - index, SocketFlags.None);
        index += size;
    }
}

1234567891011121314151617

请注意,发送数据可以分多次,因为是保持顺序的,不会乱的,接收端也可以分多次接收,但是,不能保证一次发送全部数据,最好封装一个方法,保证数据全部发送了

接收

第一步接收每一个连接

var localIp = new IPEndPoint(IPAddress.Parse(ip), port);
var tcpSocket = new Socket(serverIp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tcpSocket.Bind(localIp);

tcpSocket.Listen(10);
while (true)
{
    var client = tcpSocket.Accept();

}

12345678910

第二步,从每一个连接中接收数据

var buffer = new byte[8];
client.Receive(buffer);

private byte[] Receive(int length)
{
    var buffer = new byte[length];
    var index = 0;
    while (index < length)
    {
        var size = client.Receive(buffer, index,
            length - index, SocketFlags.None);
        index += size;
    }
    return buffer;
}

123456789101112131415

接收数据也会出现一次性接收不完,要分几次才能接收一段数据,最好是保持一问一答的方式发送和接收数据,保证数据的完整,不会出现丢包的问题

转载请保留原文链接: https://zodream.cn/blog/id/236.html