博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# Socket编程
阅读量:5861 次
发布时间:2019-06-19

本文共 5182 字,大约阅读时间需要 17 分钟。

在.NET技术大系当中,有很多服务编程的技术,比如socket、windows service、.net remoting、message queue、web service、wcf等等,这些技术都往往与网络知识紧密相关,有时还会结合多线程等技术,实现特定的需求。这里只以Socket为例,看如何运用C#进行网络编程。

熟悉Socket编程的应该都不陌生,要实现Socket,需要一个服务端程序以及一个客户端程序,服务端程序绑定IP、Port,建立侦听;客户端程序建立连接,向服务端抛出请求,通过TCP或UDP协议,获得服务端的反馈,这是一个双工通信的过程。而且最重要的是,Socket通信与具体编程语言无关,C、C++、JAVA、C#、PHP、Flex等高级编程语言都提供了相应的实现。

下面这个是个客户端Socket的简单例子,也是实际工作中曾经用过的。当时的情况是Socket服务端是用Java开发的一个程序,通过使用Socket,让两台不同网络的的机器通过前置机获取对方的信息。通过客户端发起请求,服务端监听收到请求后,进行响应处理,并把封装好的XML文档返回客户端。客户端收到XML数据后进行解析处理即可。

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
44
45
46
47
48
49
/// <summary>
/// 获取通讯中间件通过socket发送的数据,DataTable
/// </summary>
/// <param name="requestCode">请求code</param>
/// <param name="array">查询的条件,封装在数组里</param>
/// <param name="errMsg">错误提示</param>
/// <returns>经过一系列处理过后的DataTable</returns>
public 
DataTable GetDataTable(
string 
requestCode, IList<
string
> list, 
out 
string 
errMsg)
{
    
try
    
{
        
string 
ip = ConfigurationManager.AppSettings[
"ip"
].ToString().Trim();
//中间件的ip地址
        
int 
port = Convert.ToInt32(ConfigurationManager.AppSettings[
"port"
].ToString().Trim());
//中间件的端口号
        
IPEndPoint serverip = 
new 
IPEndPoint(IPAddress.Parse(ip), port);
        
using 
(Socket clientSocket = 
new 
Socket(serverip.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
        
{
            
clientSocket.Connect(serverip);
//socket连接指定中间件前置机
            
string 
outBufferString = 
string
.Empty;
//准备发送的报文
            
switch 
(requestCode)
            
{
                
case 
"111001"
:
                    
outBufferString = PrepareSendPackets(
"111001"
, list);
                    
break
;
                
case 
"111002"
:
                    
outBufferString = PrepareSendPackets(
"111002"
, list);
                    
break
;
                
case 
"111003"
:
                    
outBufferString = PrepareSendPackets(
"111003"
, list);
                    
break
;
                
default
:
                    
break
;
            
}
            
byte
[] outBuffer = 
new 
byte
[2048];
            
outBuffer = Encoding.GetEncoding(
"gbk"
).GetBytes(outBufferString);
            
clientSocket.Send(outBuffer, outBuffer.Length, 0);
//发送报文
                            
            
byte
[] inBuffer = 
new 
byte
[51200];
            
clientSocket.Receive(inBuffer, inBuffer.Length, 0);
//接收报文
            
string 
inBufferString = 
"<?xml version='1.0' encoding='gb2312' ?> "
;
            
inBufferString += Encoding.GetEncoding(
"gbk"
).GetString(inBuffer);
            
DataTable dt = ParsingPackets(requestCode, inBufferString, 
out 
errMsg);
            
return 
dt;
        
}
    
}
    
catch 
(Exception ex)
    
{
        
throw 
ex;
    
}
}

再附一个完整一点的小例子。

这个程序简单实现了客户端发送消息,服务端接收消息并反馈给客户端消息的过程。用了同步模式,是最简单的socket通信模型

服务端控制台:

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
static 
void 
Main(
string
[] args)
    
{
        
//定义一个字典用于存放用户列表
        
Dictionary<
string
string
> users = 
new 
Dictionary<
string
string
>();
                        
        
using 
(Socket socket = 
new 
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        
{
            
IPEndPoint ipe = 
new 
IPEndPoint(IPAddress.Parse(
"192.168.1.7"
), 1234);
            
socket.Bind(ipe);
            
socket.Listen(10);
                        
            
Console.WriteLine(
"socket start!"
);
                        
            
while 
(
true
)
//服务端死循环,不断提供socket服务
            
{
                
Socket clientSocket = socket.Accept();
//等待客户端请求
                        
                
IPEndPoint ip = (IPEndPoint)clientSocket.RemoteEndPoint;
                
string 
remoteAddress = ip.Address.ToString();
//远程IP地址
                        
                
byte
[] revBytes = 
new 
byte
[512];
                
clientSocket.Receive(revBytes);
//接收客户端发送的消息
                
string 
user = Encoding.Default.GetString(revBytes);
                        
                
if 
(!users.ContainsKey(remoteAddress))
                
{
                    
users.Add(remoteAddress, user);
                
}
                
Console.WriteLine(
"来自于" 
+ remoteAddress + 
"的用户:" 
+ user);
                
string 
content = 
"欢迎来到socket的世界!"
;
                
byte
[] bytes = Encoding.Default.GetBytes(content);
                
clientSocket.Send(bytes);
//发送服务端消息到客户端
                        
                
clientSocket.Shutdown(SocketShutdown.Both);
                
clientSocket.Close();
            
}
        
}
    
}

客户端WPF:

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public 
MainWindow()
    
{
        
InitializeComponent();
    
}
                   
    
private 
string 
ip;
//传入的ip
    
private 
string 
username;
//传入的用户名
                   
    
public 
MainWindow(
string 
ip, 
string 
username)
    
{
        
InitializeComponent();
                   
        
this
.ip = ip;
        
this
.username = username;
    
}
                   
    
private 
void 
button1_Click(
object 
sender, RoutedEventArgs e)
    
{
        
SendSocketPackge();
    
}
                   
    
private 
static 
Socket client;
//socket对象
                   
    
/// <summary>
    
/// 发送数据包
    
/// </summary>
    
private 
void 
SendSocketPackge()
    
{
        
//建立1个Socket对象发起TCP连接
        
client = 
new 
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        
client.Connect(IPAddress.Parse(
"192.168.1.7"
), 1234);
//连接到服务器指定IP及Port
        
string 
userSays = username + 
"说:" 
this
.textBox1.Text;
//username自己用一个字符串代替
        
client.Send(Encoding.Default.GetBytes(userSays));
//将当前的用户名发送给服务器端
                   
        
byte
[] bytes = 
new 
byte
[512];
        
client.Receive(bytes);
//接收服务端发送的消息
        
client.Shutdown(SocketShutdown.Both);
        
client.Close();
                   
        
string 
content = 
string
.Join(
" "
, DateTime.Now.ToString(), Encoding.Default.GetString(bytes));
        
listBox1.Items.Add(content);
//将消息加载到listbox列表
    
}
                   
    
private 
void 
Window_Loaded(
object 
sender, RoutedEventArgs e)
    
{
        
ip = Dns.GetHostAddresses(Dns.GetHostName())[0].ToString();
        
this
.Title = 
"来自:" 
+ ip + 
"的用户:" 
+ username;
    
}
                   
    
private 
void 
Window_Closing(
object 
sender, System.ComponentModel.CancelEventArgs e)
    
{
        
if 
(client != 
null 
&& client.Connected)
        
{
            
client.Shutdown(SocketShutdown.Both);
            
client.Close();
        
}
    
}

效果图:

服务启动时:

Center

客户端界面:

Center

点击发送后,服务端显示的消息:

Center

由于代码比较简单,就不上传项目文件了,这里简单演示了一下C#Socket通信的核心代码。读者可以在此基础上不断扩展。

本文转自 guwei4037  51CTO博客,原文链接:http://blog.51cto.com/csharper/1345244
你可能感兴趣的文章
Linux平台Java调用so库-JNI使用例子
查看>>
Web服务器压力测试工具http_load、webbench、ab、Siege使用教程
查看>>
Mac软件下载备忘
查看>>
在Linux中执行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory
查看>>
就是一个表格
查看>>
找回使用Eclipse删除的文件
查看>>
集成spring3、hibernate4、junit
查看>>
URL与ASCII
查看>>
java读取properties配置文件
查看>>
UITableview中cell重用引起的内容重复的问题
查看>>
Windows7操作系统安装教程(图文)
查看>>
除了模拟手术教学,VR在医疗领域如何应用?
查看>>
盘点5款Ubuntu监控工具解决CPU暴增问题
查看>>
java 测试IP
查看>>
用CSS做导航菜单的4个理由
查看>>
NOIP2015 运输计划 二分答案+Tarjan LCA+树上差分
查看>>
基本信息项目目标文档
查看>>
移动开发Html 5前端性能优化指南
查看>>
silverlight style和template 使用之tip
查看>>
Eclipse配置python环境
查看>>