上周由于有个项目需要用到网络通信这块,然后就花了点时间研究了一下,本来想上周就写出来的,但是突然要忙,所以等到现在。
话说对于网络通信,以前写C++的时候,天天面对着线程和Socket,所以换成C#也就没那么怕了,虽然C++下也没有掌握的多好,但毕竟只是一个小Demo,只作为了解一下过程。
自己写了一个服务端和一个客户端,刚开始比较简单,只是能达到连通,收发信息的目的,但是很粗糙。而后稍加改进呢~加上了多线程,所以能感觉更科学一些,不过自己真的很菜,代码写的不是很好看,下面分两个版本给大家表出来,希望帮助刚接触C#网络通信的朋友。
对了,还要说一点的就是,我这个小Demo是用控制台程序写的

为什么选择控制台?我也不清楚,可能是因为有个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
|
Socket ss = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipa = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
IPEndPoint iep = new IPEndPoint(ipa, 11000);
ss.Bind(iep);
ss.Listen(50);
byte [] bMessage = new byte [1024*10];
string sMsg = "Can I help you ?" ;
Socket s = ss.Accept();
while ( true )
{
try
{
s.Receive(bMessage);
sMsg = System.Text.Encoding.Unicode.GetString(bMessage);
Console.WriteLine( "Client(" + DateTime.Now.ToShortTimeString() + "):" + sMsg);
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
|
Socket ss = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress myIP = IPAddress.Parse( "192.168.xxx.xxx" );
IPEndPoint ipe = new IPEndPoint(myIP, 11000);
byte [] bMessage = null ;
string sMsg = "hello world" ;
try
{
ss.Connect(ipe);
bMessage = System.Text.Encoding.Unicode.GetBytes(sMsg.ToCharArray());
int count = ss.Send(bMessage);
if (count > 0)
{
while ( true )
{
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,如需转载请自行联系原作者