C# 如何实现简单的Socket通信(附示例)

简介:

上周由于有个项目需要用到网络通信这块,然后就花了点时间研究了一下,本来想上周就写出来的,但是突然要忙,所以等到现在。

话说对于网络通信,以前写C++的时候,天天面对着线程和Socket,所以换成C#也就没那么怕了,虽然C++下也没有掌握的多好,但毕竟只是一个小Demo,只作为了解一下过程。

自己写了一个服务端和一个客户端,刚开始比较简单,只是能达到连通,收发信息的目的,但是很粗糙。而后稍加改进呢~加上了多线程,所以能感觉更科学一些,不过自己真的很菜,代码写的不是很好看,下面分两个版本给大家表出来,希望帮助刚接触C#网络通信的朋友。

对了,还要说一点的就是,我这个小Demo是用控制台程序写的j_0016.gifj_0016.gifj_0016.gif为什么选择控制台?我也不清楚,可能是因为有个main函数的原因,在一个文件里就能搞定吧~有点懒。

简单连通版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//Server端
//创建一个socket对象,三个参数分别代表:
//AddressFamily.InterNetwork: IPV4协议,SocketType.Stream:流类型,ProtocolType.Tcp:TCP方式连接
Socket ss =  new  Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获取当前机器的IP地址,在C#中用IPAddress这个类去存放IP地址
IPAddress ipa = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
//IPEndPoint是用来把IP地址和端口号集成在一起的一个类型,在C#中叫做“网络端点”
//我这里假设服务器开的端口号是11000,这个是自己随意设置的。不是唯一
IPEndPoint iep =  new  IPEndPoint(ipa, 11000);
//之前创建的Socket与我们本机的IP和所设的端口号绑定
ss.Bind(iep);
//进行监听,也就是说我们开始侦听网络上对本机IP和11000这个端口进行连接的信息了
//参数列表官方定义为:挂起连接队列的最大长度。这个稍后单独说。
ss.Listen(50);
byte [] bMessage =  new  byte [1024*10];
string  sMsg =  "Can I help you ?" ;
//当ss这个用于监听的socket收到一个连接请求之后,会接受对方请求,并建立一个新的连接
//而新的这个s就是接下来用于真正通信的socket了。
Socket s = ss.Accept();
while  ( true )
{
       try
       {
          //bMessage = System.Text.Encoding.BigEndianUnicode.GetBytes(sMsg.ToCharArray());
          //s.Send(bMessage);
          //bMessage = null;
          //顾名思义啦,这是一个接收信息的方法,把通过网络传过来的流存入byte数组中去。
          //之所以把它写在这里是因为我的设计之初是,当socket连通成功之后,Client端会首先给Server端发一个信息。
          s.Receive(bMessage);
          //用于把byte转成string的一个方法,注意我用的是Unicode,通常我们还可以用UTF8,ASCII编解码
          //之前最坑的是当时不知道在C#下如何转,在网上看到了一个用BigEndianUnicode编码的,
          //当时没有想太多就使了,结果就是解出来各种乱码的样子,这块跟大伙提一下
          sMsg = System.Text.Encoding.Unicode.GetString(bMessage);
                     Console.WriteLine( "Client("  + DateTime.Now.ToShortTimeString() +  "):"  + sMsg);
          //接下来就是输入一个字符串,并把其转成byte数组,然后Send出去。
          bMessage = System.Text.Encoding.Unicode.GetBytes(Console.ReadLine().ToCharArray());
          s.Send(bMessage);
        }
        catch  (System.Exception ex)
        {
                                                         
        }
}

这块说一下.Listen(backlog)方法里的参数到底是表示什么东东,其实之前我也不太明白,也是写博的时候现去查的,就看到了一个比较靠谱的说法。

大概意思就是:当我们把IP和端口号暴露在网络当中,就是让其他IP去进行连接,而我们不能保证某一段时刻只有一个IP来进行连接请求,也就是说在同一时间段范围内,可能有多个连接请求,这个时候我们就需要用一个队列来维护请求连接的先后顺序。在说的细致一点呢,就是连接的过程不会是一瞬时间完成的,我们都知道TCP协议是要经过三次握手的,而在这个过程中,就有可能别的IP来进行连接请求,所以这个backlog就是表示这个队列的长度的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//Client端
//同服务器端一样,需要创建一个socket
Socket ss =  new  Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//这块主要就是把你想连接的目标主机IP地址进行一下解析,并存入IPAddress类型的一个实例当中
IPAddress myIP = IPAddress.Parse( "192.168.xxx.xxx" );
//这也同服务器是一个意思,把IP和端口号集成在一个网络端点中
IPEndPoint ipe =  new  IPEndPoint(myIP, 11000);
byte [] bMessage =  null ;
string  sMsg =  "hello world" ;
try
{
     //这是客户端的一个方法,表示连接的对象就是参数的网络端点中的IP地址和端口号
     //但是注意这里不需要返回一个新的socket作为通信socket
     //而是进行连接的这个ss就是将来一直维持此次连接的socket,直到该通道关闭或断开
     ss.Connect(ipe);
     bMessage = System.Text.Encoding.Unicode.GetBytes(sMsg.ToCharArray());
     //send方法的返回值表示已发送到socket的字节数,就像我在server端说的那样
     //这个Demo的设计思路就是连通后,客户端先向服务器端发送一个信息
     int  count = ss.Send(bMessage);
     if  (count > 0)
     {
        while  ( true )
        {
            //bMessage = null;
            ss.Receive(bMessage);
            sMsg = System.Text.Encoding.Unicode.GetString(bMessage);
            Console.WriteLine( "Server("  + DateTime.Now.ToShortTimeString() +  "):"  + sMsg);
            bMessage = System.Text.Encoding.Unicode.GetBytes(Console.ReadLine().ToCharArray());
            ss.Send(bMessage);
         }
      }
}
catch  (ArgumentNullException ae)
{
                                        
}
catch  (SocketException se)
{
      Console.WriteLine( "SocketException : {0}" , se.ToString());
}
catch  (Exception e)
{
}

这样一个简单的C#下的socket通信就写完了,说实话,我也只是懂个大概,现在很少会去深究什么了,只是到了需要的程度,才会去做一个研究,另外大家注意我这里用了try...catch,大家留意一下,我记得可能是必加的。

下面表一下另外一个稍稍改进版的,客户端没有变,主要是改服务端的代码。

哎呀,刚刚看了一下,感觉写的好垃圾,都不好意思表上来了。其实我当时写这个增进版是想了解一下C#下的多线程来着(时间有点久我给忘了,以为能归到socket通信这块呢),正好socket通信可以利用到多线程,就省得自己再去想象一个环境了,所以这个增进版主要是想说关于多线程的一些东西,这个我之后单独写一篇来讲吧,就不在这篇里表了。

不过我给大家说一下大概思路,利用多线程就是想能在Console环境下随时进行消息的发送和接收,而不是收一条才能发一条这样子。另外,我也拓展了一下,就是可以多台客户端对服务器端进行请求连接,这样就变成一对多的关系了,主要实现就是在服务器端开一个专门用于监听连接请求的线程,然后接受请求后对每个socket单独再开一个线程这样子。

具体的实现,我会在下一篇《C# 多线程如何传递两个以上参数的实现方法》中使用这个扩展版的socket通信作为例子来表给大家。










本文转自 我不会抽烟 51CTO博客,原文链接:http://blog.51cto.com/zhouhongyu1989/1410118,如需转载请自行联系原作者

目录
相关文章
|
6月前
|
存储 安全 固态存储
基于C#实现的支持文件传输的Socket聊天室
基于C#实现的支持文件传输的Socket聊天室
389 5
|
网络协议 Unix Linux
# 2个类轻松构建高效Socket通信库
本文介绍了一种通过两个类`EpollEventHandler`和`IEpollEvent`构建高效Socket通信库的方法。该库支持TCP、UDP和Unix域套接字,采用I/O多路复用技术(如epoll),提升并发处理能力。通过抽象基类和具体事件类的设计,简化了API使用,便于开发者快速上手。文章还提供了服务端与客户端的实例代码,展示其在实际项目中的应用效果。此Socket库适应嵌入式环境,功能定制性强,有助于减少外部依赖并提升维护效率。
332 97
# 2个类轻松构建高效Socket通信库
|
C# 开发者
C# 一分钟浅谈:Socket 编程基础
【10月更文挑战第7天】本文介绍了Socket编程的基础知识、基本操作及常见问题,通过C#代码示例详细展示了服务器端和客户端的Socket通信过程,包括创建、绑定、监听、连接、数据收发及关闭等步骤,帮助开发者掌握Socket编程的核心技术和注意事项。
465 3
C# 一分钟浅谈:Socket 编程基础
|
网络协议 安全 网络安全
网络编程:基于socket的TCP/IP通信。
网络编程:基于socket的TCP/IP通信。
|
12月前
|
网络协议 开发者 Python
Socket如何实现客户端和服务器间的通信
通过上述示例,展示了如何使用Python的Socket模块实现基本的客户端和服务器间的通信。Socket提供了一种简单且强大的方式来建立和管理网络连接,适用于各种网络编程应用。理解和掌握Socket编程,可以帮助开发者构建高效、稳定的网络应用程序。
620 10
|
开发框架 安全 .NET
掌握 LINQ:通过示例解释 C# 中强大的 LINQ的集运算
通过本文的示例,我们详细介绍了C#中LINQ的强大集合运算功能。LINQ提供了一种简洁、灵活和类型安全的方式来查询和操作数据集合,从而大大提高了代码的可读性和可维护性。希望本文能帮助读者更好地掌握和应用LINQ,提高开发效率。
339 13
|
网络协议 C# 开发工具
C#中简单Socket编程
1. 先运行服务器代码。服务器将开始监听指定的IP和端口,等待客户端连接。 1. 然后运行客户端代码。客户端将连接到服务器并发送消息。 1. 服务器接收到消息后,将回应客户端,并在控制台上显示接收到的消息。 1. 客户端接收到服务器的回应消息,并在控制台上显示。
796 15
|
消息中间件 网络协议 C#
C#使用Socket实现分布式事件总线,不依赖第三方MQ
`CodeWF.EventBus.Socket` 是一个轻量级的、基于Socket的分布式事件总线系统,旨在简化分布式架构中的事件通信。它允许进程之间通过发布/订阅模式进行通信,无需依赖外部消息队列服务。
C#使用Socket实现分布式事件总线,不依赖第三方MQ
|
网络协议 Linux 应用服务中间件
Socket通信之网络协议基本原理
【10月更文挑战第10天】网络协议定义了机器间通信的标准格式,确保信息准确无损地传输。主要分为两种模型:OSI七层模型与TCP/IP模型。
|
API C#
异步轮询 Web API 的实现与 C# 示例
异步轮询 Web API 的实现与 C# 示例
458 1