Socket通讯的客户端

本文主要内容:利用SocketAsyncEventArgs实现Socket客户端的通讯,其可以接收服务端的信息,向服务端发送信息。主要分两个部分:1、主要类功能的介绍;2、类代码

一、主要类功能:

  ClientUserToken.cs:主要是用于SocketAsyncEventArgs.UsetToken

  DuplexSocketAsynct.cs:主要封装了两SocketAsyncEventArgs,一个用于发送文本,另一个用于文本的接收。

二、类代码

ClientUserToken.cs

View Code
 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 using System.Net.Sockets;
7 namespace y.AircraftCarriersClient
8 {
9 class ClientUserToken
10 {
11 public Socket socket;
12 }
13 }

DuplexSocketAsync.cs

View Code
  1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 using System.Net;
7 using System.Net.Sockets;
8 using System.Threading;
9 namespace y.AircraftCarriersClient
10 {
11 class DuplexSocketAsync
12 {
13 Socket socket = null;
14 SocketAsyncEventArgs sendSocketAsync = null;
15 SocketAsyncEventArgs receiveSocketAsync = null;
16
17 ClientUserToken sendUserToken = null;
18 ClientUserToken receiveUserToken = null;
19 byte[] totalBuffer = null;
20 int bufferSize = 0;
21
22 ManualResetEvent done = null;
23 public DuplexSocketAsync()
24 {
25
26 sendSocketAsync = new SocketAsyncEventArgs();
27 receiveSocketAsync = new SocketAsyncEventArgs();
28 sendUserToken = new ClientUserToken();
29 receiveUserToken = new ClientUserToken();
30 bufferSize = 4096;
31 totalBuffer = new byte[bufferSize * 2];
32 done = new ManualResetEvent(false);
33 }
34 public void StartConnect(IPEndPoint iep)
35 {
36 socket = new Socket(iep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
37 receiveSocketAsync.RemoteEndPoint = iep;
38 Initialize();
39 receiveSocketAsync.AcceptSocket.Connect(iep);
40 bool raiseEvent = receiveUserToken.socket.ReceiveAsync(receiveSocketAsync);
41 if (!raiseEvent)
42 {
43 ProcessReceive(receiveSocketAsync);
44 }
45 }
46
47 private void Initialize()
48 {
49 sendUserToken.socket = this.socket;
50 sendSocketAsync.UserToken = sendUserToken;
51 sendSocketAsync.SetBuffer(totalBuffer, 0, bufferSize);
52 sendSocketAsync.Completed += IO_Completed;
53
54 receiveUserToken.socket = this.socket;
55 receiveSocketAsync.UserToken = receiveUserToken;
56 receiveSocketAsync.SetBuffer(totalBuffer, bufferSize, bufferSize);
57 receiveSocketAsync.Completed += IO_Completed;
58 receiveSocketAsync.AcceptSocket = this.socket;
59 }
60
61 private void IO_Completed(object sender, SocketAsyncEventArgs args)
62 {
63 switch (args.LastOperation)
64 {
65 case SocketAsyncOperation.Receive:
66 ProcessReceive(args);
67 break;
68 case SocketAsyncOperation.Send:
69 ProcessSend(args);
70 break;
71 default:
72 break;
73 //throw new ArgumentNullException("There is Invalid Operation!!");
74 }
75 }
76
77 private void ProcessReceive(SocketAsyncEventArgs args)
78 {
79 if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success)
80 {
81 string msg = Encoding.UTF8.GetString(args.Buffer, args.Offset, args.BytesTransferred);
82
83 Parameter.queueMsg.Enqueue(string.Format("[{0}]\r\n[Receive]:{1}\r\n",DateTime.Now.ToString(),msg));
84 bool raiseEvent = receiveUserToken.socket.ReceiveAsync(args);
85 if (!raiseEvent)
86 {
87 ProcessReceive(args);
88 }
89 }
90 else
91 {
92 receiveUserToken.socket.Shutdown(SocketShutdown.Receive);
93 ProcessCloseSocket();
94 }
95 }
96 public void StartReceive(SocketAsyncEventArgs args)
97 {
98 if (args.AcceptSocket != null)
99 {
100 bool raiseEvent = receiveUserToken.socket.ReceiveAsync(args);
101 if (!raiseEvent)
102 {
103 ProcessReceive(args);
104 }
105 }
106 }
107 private void ProcessSend(SocketAsyncEventArgs args)
108 {
109 if (args.SocketError != SocketError.Success)
110 {
111 sendUserToken.socket.Shutdown(SocketShutdown.Send);
112 ProcessCloseSocket();
113 }
114 }
115
116 public void ProcessCloseSocket()
117 {
118 receiveUserToken.socket = null;
119 sendUserToken.socket = null;
120 socket.Shutdown(SocketShutdown.Both);
121 receiveSocketAsync.Completed -= IO_Completed;
122 sendSocketAsync.Completed -= IO_Completed;
123 }
124
125 public void SendData(string msg)
126 {
127 byte[] msgByte = Encoding.UTF8.GetBytes(msg);
128 int len = msgByte.Length;
129 int msgLen = len;
130 while (len > bufferSize)
131 {
132 sendSocketAsync.SetBuffer(sendSocketAsync.Buffer, sendSocketAsync.Offset, bufferSize);
133 Array.Copy(msgByte, msgLen - len,sendSocketAsync.Buffer, sendSocketAsync.Offset, bufferSize);
134 sendUserToken.socket.SendAsync(sendSocketAsync);
135 len -= this.bufferSize;
136 }
137 sendSocketAsync.SetBuffer(sendSocketAsync.Buffer, sendSocketAsync.Offset, len);
138 Array.Copy(msgByte, msgLen - len, sendSocketAsync.Buffer, sendSocketAsync.Offset, len);
139 sendUserToken.socket.SendAsync(sendSocketAsync);
140 }
141 }
142 }

Parameter.cs

View Code
 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace y.AircraftCarriersClient
7 {
8 class Parameter
9 {
10 public static Queue<string> queueMsg = new Queue<string>();
11
12 }

Program.cs

View Code
 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 using System.Windows.Forms;
7 namespace y.AircraftCarriersClient
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 Application.EnableVisualStyles();
14 Application.SetCompatibleTextRenderingDefault(false);
15 Application.Run(new mainForm());
16 }
17 }
18 }

mainForm.cs

View Code
  1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9
10 using System.Net;
11 using System.Net.Sockets;
12 using System.Threading;
13 using System.Configuration;
14 namespace y.AircraftCarriersClient
15 {
16 public partial class mainForm : Form
17 {
18 public mainForm()
19 {
20 InitializeComponent();
21 }
22 private DuplexSocketAsync duplexSocketAsync = null;
23 private Thread thread = null;
24 private void btnCon_Click(object sender, EventArgs e)
25 {
26 this.btnCon.Enabled = false;
27 this.btnClose.Enabled = true;
28 try
29 {
30 thread = new Thread(ThreadStart1);
31 thread.Start();
32 duplexSocketAsync = new DuplexSocketAsync();
33 duplexSocketAsync.StartConnect(new IPEndPoint(IPAddress.Parse(this.txtIP.Text.Trim()), int.Parse(txtPort.Text.Trim())));
34 labWarning.Text = "连接成功......";
35 }
36 catch (Exception ex)
37 {
38 MessageBox.Show(ex.Message);
39 this.btnCon.Enabled = true;
40 this.btnClose.Enabled = false;
41
42 }
43 }
44
45 private delegate void SetTextControl(TextBox tb, string msg);
46 private void SetTextBox(TextBox tb, string msg)
47 {
48 if (tb.InvokeRequired)
49 {
50 SetTextControl temp = SetTextBox;
51 tb.Invoke(temp, new object[] { tb, msg });
52 }
53 else
54 {
55 tb.AppendText(msg);
56 }
57 }
58 private void SetReceiveText(object obj)
59 {
60 string msg = obj as string;
61 SetTextBox(this.txtReceive, msg);
62 }
63 object objLock = new object();
64 private void ThreadStart1()
65 {
66 while (true)
67 {
68 if (Parameter.queueMsg.Count > 0)
69 {
70 lock (objLock)
71 {
72 string msg = Parameter.queueMsg.Dequeue();
73 ThreadPool.QueueUserWorkItem(SetReceiveText, msg);
74 }
75 }
76 else
77 {
78 Thread.Sleep(100);
79 }
80 }
81 }
82
83 private void btnClose_Click(object sender, EventArgs e)
84 {
85 duplexSocketAsync.ProcessCloseSocket();
86 duplexSocketAsync = null;
87 this.btnCon.Enabled = true;
88 this.btnClose.Enabled = false;
89 this.labWarning.Text = "已断开连接......";
90 }
91
92 private void btnSend_Click(object sender, EventArgs e)
93 {
94 if (duplexSocketAsync != null)
95 {
96 duplexSocketAsync.SendData(this.txtSend.Text.Trim());
97 this.txtReceive.AppendText(string.Format("\r\n[{0}]\r\n[Send]:{1}\r\n", DateTime.Now.ToString(), this.txtSend.Text.Trim()));
98 this.txtSend.Clear();
99 }
100 else
101 {
102 MessageBox.Show("连接已断开。");
103 }
104 }
105
106 private void mainForm_FormClosed(object sender, FormClosedEventArgs e)
107 {
108 Environment.Exit(0);
109 }
110
111 private void btnClear_Click(object sender, EventArgs e)
112 {
113 this.txtReceive.Clear();
114 }
115
116 private void mainForm_Load(object sender, EventArgs e)
117 {
118 this.txtIP.Text = ConfigurationManager.AppSettings["IP"];
119 this.txtPort.Text = ConfigurationManager.AppSettings["Port"];
120 }
121 }
122 }

App.config

View Code
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3 <appSettings>
4 <add key="IP" value="127.0.0.1"/>
5 <add key="Port" value="2345"/>
6 </appSettings>
7 </configuration>

mainForm的主界面:

posted @ 2011-08-11 12:57  走过留痕  阅读(855)  评论(1编辑  收藏  举报