iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >在c#中使用Socket实现一个tcp协议
  • 615
分享到

在c#中使用Socket实现一个tcp协议

2023-06-06 10:06:43 615人浏览 安东尼
摘要

这篇文章给大家介绍在C#中使用Socket实现一个tcp协议,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、概述UDP和TCP是网络通讯常用的两个传输协议,C#一般可以通过Socket来实现UDP和TCP通讯,由于.

这篇文章给大家介绍在C#中使用Socket实现一个tcp协议,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

一、概述

UDP和TCP是网络通讯常用的两个传输协议,C#一般可以通过Socket来实现UDP和TCP通讯,由于.net框架通过UdpClient、TcpListener 、TcpClient这几个类对Socket进行了封装,使其使用更加方便, 本文就通过这几个封装过的类讲解一下相关应用。

二、基本应用:连接、发送、接收

服务端建立侦听并等待连接:

TcpListener tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 9000);tcpListener.Start();if (tcpListener.Pending()){   TcpClient client = tcpListener.AcceptTcpClient();   Console.WriteLine("Connected"); }

服务端是通过AcceptTcpClient方法获得TcpClient对象,而客户端是直接创建TcpClient对象。

TcpClient tcpClient = new TcpClient();tcpClient.Connect("127.0.0.1", 9000);

发送数据TcpClient对象创建后,发送接收都通过TcpClient对象完成。

发送数据:

TcpClient tcpClient = new TcpClient();    tcpClient.Connect("127.0.0.1", 9000);    NetworkStream netStream = tcpClient.GetStream();    int Len = 1024;    byte[] datas = new byte[Len];    netStream.Write(datas, 0, Len);        netStream.Close();    tcpClient.Close();

接收数据:

TcpClient client = tcpListener.AcceptTcpClient();Console.WriteLine("Connected");   NetworkStream stream = client.GetStream(); var remote = client.Client.RemoteEndPoint; byte[] data = new byte[1024]; while (true) {   if (stream.DataAvailable)   {    int len = stream.Read(data, 0, 1024);    Console.WriteLine($"From:{remote}:Received ({len})");   }  Thread.Sleep(1); }

三、 粘包问题

和UDP不太一样,TCP连接不会丢包,但存在粘包问题。(严格来说粘包这个说法是不严谨的,因为TCP通讯是基于流的,没有包的概念,包只是使用者自己的理解。) 下面分析一下粘包产生的原因及解决办法。

TCP数据通讯是基于流来实现的,类似一个队列,当有数据发送过来时,操作系统就会把发送过来的数据依次放到这个队列中,对发送者而言,数据是一片一片发送的,所以自然会认为存在数据包的概念,但对于接收者而言,如果没有及时去取这些数据,这些数据依次存放在队列中,彼此之间并无明显间隔,自然就粘包了。

还有一种情况粘包是发送端造成的,有时我们调用发送代码时,操作系统可能并不会立即发送,而是放到缓存区,当缓存区达到一定数量时才真正发送。 

要解决粘包问题,大致有以下几个方案。

约定数据长度,发送端的数据都是指定长度,比如1024;接收端取数据时也取同样长度,不够长度就等待,保证取到的数据和发送端一致;

接收端取数据的频率远大于发送端,比如发送端每1秒发送一段数据,接收端每0.1秒去取一次数据,这样基本可以保证数据不会粘起来;

以上两个方案都要求发送端需要立即发送,不可缓存数据。而且这两种方案都有缺陷:首先,第一种方案:如果要包大小一致的话,如果约定的包比较大,肯定有较多数据冗余,浪费网络资源,如果包较小,连接就比较频繁,效率不高。

其次,第二种方案:这个方案只能在理想环境下可以实现,当服务端遭遇一段时间的计算压力时可能会出现意外,不能完全保证。

比较完善的解决方案就是对接收到的数据进行预处理:首先通过定义特殊的字符组合作为包头和包尾,如果传输ASCII字符,可以用0x02表示开始(STX),用0x03表示结束(ETX),比如:STX ‘H' ‘e' ‘l' ‘l' ‘o' ETX (二进制数据: 02 48 65 6C 6C 6F 03)。如果数据较长可以在包头留出固定位置存放包长度, 如:

02 00 05 48 65 6C 6C 6F 03

其中02 05 就表示正文长度为5个字节,可以进行校验。

虽然第三种方案比较严谨,但相对复杂,在传输比较可靠、应用比较简单的场景下,也可以采用前面两种解决方案。

四、 一个完整的例程

服务端:

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Threading.Tasks;namespace TCPServer{ class Program {   static void Main(string[] args)  {    TcpListener tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 9000);   tcpListener.Start();   while (true)   {    if (tcpListener.Pending())    {     TcpClient client = tcpListener.AcceptTcpClient();     Console.WriteLine("Connected");          Task.Run(() =>     {       NetworkStream stream = client.GetStream();      var remote = client.Client.RemoteEndPoint;            while (true)      {       if (stream.DataAvailable)       {        byte[] data = new byte[1024];        int len = stream.Read(data, 0, 1024);        string Name = Encoding.UTF8.GetString(data,0,len);        var senddata = Encoding.UTF8.GetBytes("Hello:" + Name);        stream.Write(senddata, 0, senddata.Length);       }       if (!client.IsOnline())       {        Console.WriteLine("Connect Closed.");        break;       }       Thread.Sleep(1);      }     });    }    Thread.Sleep(1);   }  } } public static class TcpClientEx {  public static bool IsOnline(this TcpClient client)  {   return !((client.Client.Poll(15000, SelectMode.SelectRead) && (client.Client.Available == 0)) || !client.Client.Connected);  } }}

客户端:

using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Net.Sockets;using System.Text;using System.Threading;using System.Threading.Tasks;namespace TCP_Clent{ class Program {  static void Main(string[] args)  {   ThreadPool.SetMinThreads(100, 100);   ThreadPool.SetMaxThreads(200, 200);    Parallel.For(1, 10, x =>   {    SendData("Tom");   });   Console.WriteLine("All Completed!");   Console.ReadKey();  }  private static void SendData(string Name)  {   Task.Run(() =>   {    Console.WriteLine("Start");    TcpClient tcpClient = new TcpClient();    tcpClient.Connect("127.0.0.1", 9000);    Console.WriteLine("Connected");    NetworkStream netStream = tcpClient.GetStream();    Task.Run(() =>    {     Thread.Sleep(100);     while (true)     {      if (!tcpClient.Client.Connected)      {       break;      }      if (netStream == null)      {       break;      }      try      {       if (netStream.DataAvailable)       {        byte[] data = new byte[1024];        int len = netStream.Read(data, 0, 1024);        var message = Encoding.UTF8.GetString(data, 0, len);        Console.WriteLine(message);       }      }      catch      {       break;      }      Thread.Sleep(10);     }    });    for (int i = 0; i < 100; i++)    {     byte[] datas = Encoding.UTF8.GetBytes(Name);     int Len = datas.Length;     netStream.Write(datas, 0, Len);     Thread.Sleep(1000);    }    netStream.Close();    netStream = null;    tcpClient.Close();    Console.WriteLine("Completed");   });  }   }}

关于在c#中使用Socket实现一个tcp协议就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: 在c#中使用Socket实现一个tcp协议

本文链接: https://www.lsjlt.com/news/246396.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 在c#中使用Socket实现一个tcp协议
    这篇文章给大家介绍在c#中使用Socket实现一个tcp协议,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、概述UDP和TCP是网络通讯常用的两个传输协议,C#一般可以通过Socket来实现UDP和TCP通讯,由于....
    99+
    2023-06-06
  • Android Socket使用TCP协议实现手机投屏
    本节主要通过实战来了解Socket在TCP/IP协议中充当的是一个什么角色,有什么作用。通过Socket使用TCP协议实现局域网内手机A充当服务端,手机B充当客户端,手机B连接手机A,手机A获取屏幕数据转化为Bitmap,通过Socket传...
    99+
    2023-09-06
    tcp/ip Socket
  • python用socket实现协议TCP长连接框架
    “ 使用python实现协议中常见的TCP长连接框架。” 分析多了协议就会发现,很多的应用,特别是游戏类和IM类应用,它们的协议会使用长连接的方式,...
    99+
    2024-04-02
  • python如何使用socket实现TCP协议长连接框架
    这篇文章主要介绍了python如何使用socket实现TCP协议长连接框架,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。分析多了协议就会发现,很多的应用,特别是游戏类和IM类...
    99+
    2023-06-29
  • python中怎么用socket实现协议TCP长连接框架
    这篇文章主要介绍“python中怎么用socket实现协议TCP长连接框架”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“python中怎么用socket实现协议TCP长连接框架”文章能帮助大家解决问...
    99+
    2023-06-29
  • 在Java项目中使用Socket 如何实现 一个TCP服务端
    在Java项目中使用Socket 如何实现 一个TCP服务端?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1 Java Socket简介  所谓socket 通...
    99+
    2023-05-31
    java socket tcp
  • .NET编程——利用C#实现TCP协议的异步通信Socket套接字(WinForm)
    本文将介绍利用基于TCP通信协议的Socket实现服务器与客户端之间的数据传输。 目录 前言 计算机通信 创建服务器 服务器通信 创建客户端 客户端通信 前言         TCP/IP(Transmission Control Pr...
    99+
    2023-09-04
    tcp/ip c# mysql 服务器
  • 怎么基于Kotlin实现一个简单的TCP自定义协议
    这篇文章主要讲解了“怎么基于Kotlin实现一个简单的TCP自定义协议”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么基于Kotlin实现一个简单的TCP...
    99+
    2024-04-02
  • 如何使用linux shell 脚本实现tcp/upd协议通讯
    本篇内容主要讲解“如何使用linux shell 脚本实现tcp/upd协议通讯”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用linux shell 脚本实现tcp/upd协议通讯”吧!...
    99+
    2023-06-09
  • 使用TCP协议在Go语言中进行网络通信
    目前编程网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《使用TCP协议在Go语言中进行网络通信》,也希望能帮助到大家,如果阅读完后真的对你学习Go...
    99+
    2024-04-04
  • TCP协议中SequenceNumber和Ack Number是怎样一个对应关系
    在TCP协议中,Sequence Number(序列号)和Acknowledgment Number(确认号)是一对相关的值,用于实...
    99+
    2023-08-08
    TCP
  • 在C# 中使用Socke实现一个UDP
    这篇文章给大家介绍在C# 中使用Socke实现一个UDP,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、概述UDP和TCP是网络通讯常用的两个传输协议,C#一般可以通过Socket来实现UDP和TCP通讯,由于.NE...
    99+
    2023-06-06
  • Python使用 TCP协议实现智能聊天机器人功能
    编写聊天程序的服务端代码和客户端代码。完成后,先启动服务端代码,然 后启动客户端程序输人问题,服务端可以返回相应的答案。要求服务端代码具 有一定的智能,能够根据不完整的问题识别客户端...
    99+
    2024-04-02
  • linux中shell脚本如何实现tcp/upd协议通讯
    小编给大家分享一下linux中shell脚本如何实现tcp/upd协议通讯,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!linux 设备里面有个比较特殊的文件: ...
    99+
    2023-06-13
  • 怎么在Java中使用Socket实现一个多人聊天室
    本篇文章给大家分享的是有关怎么在Java中使用Socket实现一个多人聊天室,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。流程首先建立一个服务器端,构建ServerSocket...
    99+
    2023-06-14
  • 在C++中使用HP-Socket
    目录1、简介2、使用方式3、实现简单线程池4、实现TCP客户端5、实现TCP服务端6、实现Http客户端1、简介 HP-Socket 是一套通用的高性能 TCP/UDP /HTTP...
    99+
    2024-04-02
  • go语言中的udp协议及TCP通讯实现示例
    目录udp协议server端client端TCP通讯(基本)服务端客户端TCP通讯并发服务器服务端客户端udp协议 server端 package main import ( "f...
    99+
    2024-04-02
  • 如何使用C#基于Socket的TCP通信实现聊天室
    这篇文章给大家分享的是有关如何使用C#基于Socket的TCP通信实现聊天室的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体内容如下一.Socket(套接字)通信概念套接字(socket)是通信的基石,用于描述...
    99+
    2023-06-29
  • 使用 Java 类 实现Http协议
    目录Java实现Http协议一、协议请求的定义二、响应协议的定义三、编码常量定义四、客户端的实现五、服务端的实现六、ProtocolUtils工具类的实现七、ByteUtils类的实...
    99+
    2024-04-02
  • java如何利用socket通信实现Modbus-RTU通信协议
    小编给大家分享一下java如何利用socket通信实现Modbus-RTU通信协议,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!ModbusModbus是一种串行...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作