参考了一些网上的例子,感觉挺有意思,于是自己也尝试了一下,如下:

代码如下:

Code
1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Text;
7
using System.Windows.Forms;
8
9
using System.Threading;
10
using System.Net.Sockets;
11
using System.Net;
12
using System.Collections;
13
14
namespace TcpSocketServer
15

{
16
public partial class Form1 : Form
17
{
18
public Form1()
19
{
20
InitializeComponent();
21
}
22
23
define Variable#region define Variable
24
25
private static int listenport = 6666;
26
27
private Socket clientsocket;
28
29
private ArrayList clients;
30
31
private Thread clientservice;
32
33
private Thread threadListen;
34
35
#endregion
36
37
/**//// <summary>
38
/// Button Event
39
/// </summary>
40
/// <param name="sender"></param>
41
/// <param name="e"></param>
42
private void button1_Click(object sender, EventArgs e)
43
{
44
//开始监听
45
try
46
{
47
threadListen = new Thread(new ThreadStart(StartListening));
48
label1.Text = "listening
.";
49
threadListen.Start();
50
}
51
catch (System.Exception er)
52
{
53
MessageBox.Show(er.Message, "完成", MessageBoxButtons.OK, MessageBoxIcon.Stop);
54
}
55
}
56
57
/**//// <summary>
58
/// Start Listen
59
/// </summary>
60
private void StartListening()
61
{
62
TcpListener listener = new TcpListener(listenport);
63
listener.Start();
64
//label1.Text = "listening
.";
65
while (true)
66
{
67
try
68
{
69
Socket s = listener.AcceptSocket();
70
clientsocket = s;
71
clientservice = new Thread(new ThreadStart(ServiceClient));
72
clientservice.Start();
73
}
74
catch (Exception ex)
75
{
76
MessageBox.Show("listening Error: " + ex.Message);
77
}
78
}
79
}
80
81
delegate event#region delegate event
82
/**//// <summary>
83
/// 添加子项代理
84
/// </summary>
85
/// <param name="cc"></param>
86
private delegate void _deleAdditems(Client cc);
87
/**//// <summary>
88
/// 去除元素代理
89
/// </summary>
90
/// <param name="x"></param>
91
private delegate void moveElement(int x);
92
/**//// <summary>
93
/// 去除列表元素代理
94
/// </summary>
95
/// <param name="x"></param>
96
private delegate void movelist(Client x);
97
/**//// <summary>
98
/// 添加串代理
99
/// </summary>
100
/// <param name="str"></param>
101
private delegate void deleAddStr(string str);
102
103
private void Additems(Client cc)
104
{
105
try
106
{
107
//判断与创建textBox_ID控件的线程(这里是主线程)是否在同一个线程中
108
if (this.lbClients.InvokeRequired)
109
{
110
_deleAdditems changer = new _deleAdditems(Additems);
111
//在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托
112
this.Invoke(changer, new object[]
{ cc });
113
}
114
else
115
{
116
#region
117
//lock (lockObject)
118
//{
119
// Monitor.PulseAll(lockObject);
120
//}
121
#endregion
122
lbClients.Items.Add(cc);
123
}
124
}
125
catch (Exception ex)
126
{
127
MessageBox.Show(ex.Message);
128
}
129
}
130
131
private void AddStr(string str)
132
{
133
try
134
{
135
if (this.textBox1.InvokeRequired)
136
{
137
deleAddStr changer = new deleAddStr(AddStr);
138
this.Invoke(changer, new object[]
{ str });
139
}
140
else
141
this.textBox1.Text = str;
142
}
143
catch (Exception ex)
144
{
145
MessageBox.Show(ex.Message);
146
}
147
}
148
149
private void movel(Client x)
150
{
151
try
152
{
153
if (this.lbClients.InvokeRequired)
154
{
155
movelist changer = new movelist(movel);
156
this.Invoke(changer, new object[]
{ x });
157
}
158
else
159
lbClients.Items.Remove(x);
160
}
161
catch (Exception ex)
162
{
163
MessageBox.Show(ex.Message);
164
}
165
}
166
167
private void MoveEle(int x)
168
{
169
try
170
{
171
if (this.clients.IsSynchronized)
172
{
173
moveElement changer = new moveElement(MoveEle);
174
this.Invoke(changer, new object[]
{ x });
175
}
176
else
177
this.clients.RemoveAt(x);
178
}
179
catch (Exception ex)
180
{
181
MessageBox.Show(ex.Message);
182
}
183
}
184
#endregion
185
186
/**//// <summary>
187
/// ServiceClient
188
/// </summary>
189
private void ServiceClient()
190
{
191
Socket client = clientsocket;
192
bool keepalive = true;
193
194
while (keepalive)
195
{
196
Byte[] buffer = new Byte[1024];
197
int bufLen = 0;
198
try
199
{
200
bufLen = client.Available;
201
202
client.Receive(buffer, 0, bufLen, SocketFlags.None);
203
204
if (bufLen == 0)
205
continue;
206
}
207
catch (Exception ex)
208
{
209
MessageBox.Show("Receive Error:" + ex.Message);
210
return;
211
}
212
213
string clientcommand = System.Text.Encoding.ASCII.GetString(buffer).Substring(0, bufLen);
214
string[] tokens = clientcommand.Split(new Char[]
{ '|' });
215
//Console.WriteLine(clientcommand);
216
//this.textBox1.Text = clientcommand;
217
AddStr(clientcommand);
218
219
if (tokens[0] == "CONN")
220
{
221
for (int n = 0; n < clients.Count; n++)
222
{
223
Client cl = (Client)clients[n];
224
SendToClient(cl, "JOIN|" + tokens[1]);
225
}
226
EndPoint ep = client.RemoteEndPoint;
227
Client c = new Client(tokens[1], ep, clientservice, client);
228
229
string message = "LIST|" + GetChatterList() + "\r\n";
230
SendToClient(c, message);
231
clients.Add(c);
232
//lbClients.Items.Add(c);
233
Additems(c);
234
235
}
236
if (tokens[0] == "CHAT")
237
{
238
for (int n = 0; n < clients.Count; n++)
239
{
240
Client cl = (Client)clients[n];
241
SendToClient(cl, clientcommand);
242
}
243
}
244
if (tokens[0] == "PRIV")
245
{
246
string destclient = tokens[3];
247
for (int n = 0; n < clients.Count; n++)
248
{
249
Client cl = (Client)clients[n];
250
if (cl.Name.CompareTo(tokens[3]) == 0)
251
SendToClient(cl, clientcommand);
252
if (cl.Name.CompareTo(tokens[1]) == 0)
253
SendToClient(cl, clientcommand);
254
}
255
}
256
if (tokens[0] == "GONE")
257
{
258
int remove = 0;
259
bool found = false;
260
int c = clients.Count;
261
for (int n = 0; n < clients.Count; n++)
262
{
263
Client cl = (Client)clients[n];
264
SendToClient(cl, clientcommand);
265
if (cl.Name.CompareTo(tokens[1]) == 0)
266
{
267
remove = n;
268
found = true;
269
movel(cl);
270
//lbClients.Items.Remove(cl);
271
}
272
}
273
if (found)
274
{
275
clients.RemoveAt(remove);
276
}
277
client.Close();
278
keepalive = false;
279
}
280
}
281
}
282
283
/**//// <summary>
284
/// 获取列表元素
285
/// </summary>
286
/// <returns></returns>
287
private string GetChatterList()
288
{
289
string result = "";
290
291
for (int i = 0; i < clients.Count; i++)
292
{
293
result += ((Client)clients[i]).Name + "|";
294
}
295
return result;
296
}
297
298
/**//// <summary>
299
/// 发送到客户端
300
/// </summary>
301
/// <param name="cl"></param>
302
/// <param name="clientCommand"></param>
303
private void SendToClient(Client cl, string clientCommand)
304
{
305
Byte[] message = System.Text.Encoding.ASCII.GetBytes(clientCommand);
306
Socket s = cl.Sock;
307
if (s.Connected)
308
{
309
s.Send(message, message.Length, 0);
310
}
311
}
312
313
/**//// <summary>
314
/// Form Load Event
315
/// </summary>
316
/// <param name="sender"></param>
317
/// <param name="e"></param>
318
private void Form1_Load(object sender, EventArgs e)
319
{
320
clients = new ArrayList();
321
}
322
323
}
324
}
服务器端还有一个类
Client.cs

Code
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Net;
5
using System.Net.Sockets;
6
using System.Threading;
7
8
9
namespace TcpSocketServer
10

{
11
public class Client
12
{
13
private Thread clthread;
14
private EndPoint endpoint;
15
private string name;
16
private Socket sock;
17
18
/**//// <summary>
19
/// 客户端类
20
/// </summary>
21
/// <param name="_name">名称</param>
22
/// <param name="_endpoint"></param>
23
/// <param name="_thread"></param>
24
/// <param name="_sock"></param>
25
public Client(string _name, EndPoint _endpoint, Thread _thread, Socket _sock)
26
{
27
// TODO: 在此处添加构造函数逻辑
28
clthread = _thread;
29
endpoint = _endpoint;
30
name = _name;
31
sock = _sock;
32
}
33
34
/**//// <summary>
35
/// 重写ToString() 方法
36
/// </summary>
37
/// <returns></returns>
38
public override string ToString()
39
{
40
return endpoint.ToString() + " : " + name;
41
}
42
/**//// <summary>
43
/// 客户端线程
44
/// </summary>
45
public Thread CLThread
46
{
47
get
{ return clthread; }
48
set
{ clthread = value; }
49
}
50
/**//// <summary>
51
/// 客户端地址
52
/// </summary>
53
public EndPoint Host
54
{
55
get
{ return endpoint; }
56
set
{ endpoint = value; }
57
}
58
/**//// <summary>
59
/// 客户端姓名
60
/// </summary>
61
public string Name
62
{
63
get
{ return name; }
64
set
{ name = value; }
65
}
66
/**//// <summary>
67
/// 客户端套接字
68
/// </summary>
69
public Socket Sock
70
{
71
get
{ return sock; }
72
set
{ sock = value; }
73
}
74
}
75
}
76
客户端

Code
1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Text;
7
using System.Windows.Forms;
8
using System.Net;
9
using System.Net.Sockets;
10
using System.Threading;
11
using System.IO;
12
13
namespace TcpSocketClient
14

{
15
public partial class Form1 : Form
16
{
17
public Form1()
18
{
19
InitializeComponent();
20
}
21
/**//// <summary>
22
/// Form Load Event
23
/// </summary>
24
/// <param name="sender"></param>
25
/// <param name="e"></param>
26
private void Form1_Load(object sender, EventArgs e)
27
{
28
// to do?
29
}
30
31
Define Variable#region Define Variable
32
33
/**//// <summary>
34
/// 数据流
35
/// </summary>
36
private NetworkStream ns;
37
/**//// <summary>
38
/// 读取流
39
/// </summary>
40
private StreamReader sr;
41
/**//// <summary>
42
/// TCP连接
43
/// </summary>
44
private TcpClient clientsocket;
45
/**//// <summary>
46
/// 连接与否
47
/// </summary>
48
private bool connected;
49
/**//// <summary>
50
/// 接收线程
51
/// </summary>
52
private Thread receive;
53
/**//// <summary>
54
/// 服务器地址
55
/// </summary>
56
private string serveraddress = "192.168.1.40";
57
/**//// <summary>
58
/// 服务器端口
59
/// </summary>
60
private int serverport = 6666;
61
/**//// <summary>
62
/// 客户端名称
63
/// </summary>
64
private string clientname;
65
66
#endregion
67
68
/**//// <summary>
69
/// EstablishConnection
70
/// </summary>
71
private void EstablishConnection()
72
{
73
statusBar1.Text = "正在连接到服务器
";
74
75
try
76
{
77
clientsocket = new TcpClient(serveraddress, serverport);
78
ns = clientsocket.GetStream();
79
sr = new StreamReader(ns);
80
connected = true;
81
}
82
catch (Exception)
83
{
84
MessageBox.Show("不能连接到服务器!", "错误",
85
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
86
statusBar1.Text = "已断开连接";
87
}
88
}
89
/**//// <summary>
90
/// Register With Server
91
/// </summary>
92
private void RegisterWithServer()
93
{
94
lbChatters.Items.Clear();
95
96
clientname = clientName.Text;
97
try
98
{
99
string command = "CONN|" + clientname; //+"\r\n";
100
Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
101
ns.Write(outbytes, 0, outbytes.Length);
102
103
104
string serverresponse = sr.ReadLine();
105
serverresponse.Trim();
106
string[] tokens = serverresponse.Split('|');
107
108
if (tokens[0] == "LIST")
109
{
110
statusBar1.Text = "已连接";
111
btnDisconnect.Enabled = true;
112
}
113
if (tokens[1] != "")
114
{
115
for (int n = 1; n < tokens.Length; n++)
116
lbChatters.Items.Add(tokens[n].Trim(new char[]
{ '\r', '\n' }));
117
}
118
this.Text = clientname + ":已连接到服务器";
119
120
}
121
catch (Exception ex)
122
{
123
MessageBox.Show("注册时发生错误!" + ex.Message, "错误",
124
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
125
connected = false;
126
}
127
}
128
/**//// <summary>
129
/// Receive Chat Content
130
/// </summary>
131
private void ReceiveChat()
132
{
133
bool keepalive = true;
134
while (keepalive)
135
{
136
try
137
{
138
Byte[] buffer = new Byte[1024]; // 2048???
139
ns.Read(buffer, 0, buffer.Length);
140
string chatter = System.Text.Encoding.ASCII.GetString(buffer);
141
string[] tokens = chatter.Split(new Char[]
{ '|' });
142
143
if (tokens[0] == "CHAT")
144
{
145
rtbChatIn.AppendText(tokens[1]);
146
// if(logging)
147
// logwriter.WriteLine(tokens[1]);
148
}
149
if (tokens[0] == "PRIV")
150
{
151
rtbChatIn.AppendText("Private from ");
152
rtbChatIn.AppendText(tokens[1].Trim());
153
rtbChatIn.AppendText(tokens[2] + "\r\n");
154
// if(logging)
155
// {
156
// logwriter.Write("Private from ");
157
// logwriter.Write(tokens[1].Trim() );
158
// logwriter.WriteLine(tokens[2] + "\r\n");
159
// }
160
}
161
if (tokens[0] == "JOIN")
162
{
163
rtbChatIn.AppendText(tokens[1].Trim());
164
rtbChatIn.AppendText(" has joined the Chat\r\n");
165
// if(logging)
166
// {
167
// logwriter.WriteLine(tokens[1]+" has joined the Chat");
168
// }
169
string newguy = tokens[1].Trim(new char[]
{ '\r', '\n' });
170
lbChatters.Items.Add(newguy);
171
}
172
if (tokens[0] == "GONE")
173
{
174
rtbChatIn.AppendText(tokens[1].Trim());
175
rtbChatIn.AppendText(" has left the Chat\r\n");
176
// if(logging)
177
// {
178
// logwriter.WriteLine(tokens[1]+" has left the Chat");
179
// }
180
lbChatters.Items.Remove(tokens[1].Trim(new char[]
{ '\r', '\n' }));
181
}
182
if (tokens[0] == "QUIT")
183
{
184
ns.Close();
185
clientsocket.Close();
186
keepalive = false;
187
statusBar1.Text = "服务器端已停止";
188
connected = false;
189
btnSend.Enabled = false;
190
btnDisconnect.Enabled = false;
191
}
192
}
193
catch (Exception)
{ }
194
}
195
}
196
/**//// <summary>
197
/// Quit Chat
198
/// </summary>
199
private void QuitChat()
200
{
201
if (connected)
202
{
203
try
204
{
205
string command = "GONE|" + clientname;
206
Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
207
ns.Write(outbytes, 0, outbytes.Length);
208
clientsocket.Close();
209
}
210
catch (Exception ex)
211
{
212
MessageBox.Show(ex.Message);
213
}
214
}
215
// if(logging)
216
// logwriter.Close();
217
if (receive != null && receive.IsAlive)
218
receive.Abort();
219
this.Text = "客户端";
220
221
connected = false;
222
223
}
224
/**//// <summary>
225
/// Send Button
226
/// </summary>
227
/// <param name="sender"></param>
228
/// <param name="e"></param>
229
private void btnSend_Click(object sender, EventArgs e)
230
{
231
if (connected)
232
{
233
try
234
{
235
string command = "CHAT|" + clientname + ": " + ChatOut.Text + "\r\n";
236
Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
237
ns.Write(outbytes, 0, outbytes.Length);
238
//clientsocket.Close();
239
}
240
catch (Exception ex)
241
{
242
MessageBox.Show(ex.Message);
243
}
244
}
245
246
}
247
/**//// <summary>
248
/// Connect Button
249
/// </summary>
250
/// <param name="sender"></param>
251
/// <param name="e"></param>
252
private void btnConnect_Click(object sender, EventArgs e)
253
{
254
EstablishConnection();
255
RegisterWithServer();
256
if (connected)
257
{
258
receive = new Thread(new ThreadStart(ReceiveChat));
259
receive.Start();
260
}
261
}
262
/**//// <summary>
263
/// Disconnect Button
264
/// </summary>
265
/// <param name="sender"></param>
266
/// <param name="e"></param>
267
private void btnDisconnect_Click(object sender, EventArgs e)
268
{
269
QuitChat();
270
}
271
}
272
}
如图: