套接字编程Word文档格式.docx
《套接字编程Word文档格式.docx》由会员分享,可在线阅读,更多相关《套接字编程Word文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
(socketWatch)用来监听的
绑定到一个IP地址和一个端口上
开启侦听,等待接授客户端的连接
当有连接时创建一个用于和连接进来的客户端进行通信的socket(socketConnection)
即续监听,等侍下一个客户的连接
代码如下:
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Net;
//IPAdress,IPEndPoint(ip和端口)类
usingSystem.Net.Sockets;
usingSystem.Threading;
usingSystem.IO;
namespaceMyChatRoomServer
{
publicpartialclassFChatServer:
Form
publicFChatServer()
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls=false;
//关闭对文本框
的跨线程操作检查
}
ThreadthreadWatch=null;
//负责监听客户端连接请求的线程
SocketsocketWatch=null;
//负责监听的套接字
privatevoidbtnBeginListen_Click(objectsender,EventArgse)
//创建服务端负责监听的套接字,参数(使用IP4寻址协议,使用流式连接,使用TCP协议传输数据)
socketWatch=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//获得文本框中的IP地址对象
IPAddressaddress=IPAddress.Parse(txtIP.Text.Trim());
//创建包含ip和port的网络节点对象
IPEndPointendpoint=newIPEndPoint(address,int.Parse(txtPort.Text.Trim()));
//将负责监听的套接字绑定到唯一的IP和端口上
socketWatch.Bind(endpoint);
//设置监听队列的长度
socketWatch.Listen(10);
//创建负责监听的线程,并传入监听方法
threadWatch=newThread(WatchConnecting);
threadWatch.IsBackground=true;
//设置为后台线程
threadWatch.Start();
//开启线程
ShowMsg("
服务器启动监听成功~"
);
//IPEndPoint
//socketWatch.Bind(
//保存了服务器端所有负责和客户端通信的套接字
Dictionary<
string,Socket>
dict=newDictionary<
();
//保存了服务器端所有负责调用通信套接字.Receive方法的线程
string,Thread>
dictThread=newDictionary<
//SocketsokConnection=null;
///<
summary>
///监听客户端请求的方法
/summary>
voidWatchConnecting()
while(true)//持续不断的监听新的客户端的连接请求
//开始监听客户端连接请求,注意:
Accept方法,会阻断当前的线程!
SocketsokConnection=socketWatch.Accept();
//一旦监听到客户端的请求,就返回一个负责和该客户端通信的套接字sokConnection
//sokConnection.Receive
//向列表控件中添加一个客户端的ip端口字符串,作为客户端的唯一标识
lbOnline.Items.Add(sokConnection.RemoteEndPoint.ToString());
//将与客户端通信的套接字对象sokConnection添加到键值对集合中,并以客户端IP端口作为键
dict.Add(sokConnection.RemoteEndPoint.ToString(),sokConnection);
//创建通信线程
ParameterizedThreadStartpts=newParameterizedThreadStart(RecMsg);
Threadthr=newThread(pts);
thr.IsBackground=true;
//设置为
thr.Start(sokConnection);
//启动线程并为线程要调用的方法RecMsg传入参数sokConnection
dictThread.Add(sokConnection.RemoteEndPoint.ToString(),thr);
//将线程保存在字典里,方便大家以后做“踢人”功能的时候用
客户端连接成功!
"
+sokConnection.RemoteEndPoint.ToString());
//sokConnection.RemoteEndPoint中保存的是当前连接客户端的Ip和端口
///服务端负责监听客户端发送来的数据的方法
voidRecMsg(objectsocketClientPara)
SocketsocketClient=socketClientParaasSocket;
while(true)
//定义一个接收用的缓存区(2M字节数组)
byte[]arrMsgRec=newbyte[1024*1024*2];
//将接收到的数据存入arrMsgRec数组,并返回真正接收到的数据的长度
intlength=-1;
try
length=socketClient.Receive(arrMsgRec);
catch(SocketExceptionex)
异常:
+ex.Message);
//从通信套接字集合中删除被中断连接的通信套接字对象
dict.Remove(socketClient.RemoteEndPoint.ToString());
//从通信线程
结合中删除被终端连接的通信线程对象
dictThread.Remove(socketClient.RemoteEndPoint.ToString());
//从列表中移除被中断的连接ip:
Port
lbOnline.Items.Remove(socketClient.RemoteEndPoint.ToString());
break;
catch(Exceptionex)
if(arrMsgRec[0]==0)//判断发送过来的数据的第一个元素是0,则代表发送来的是文字数据
//此时是将数组所有的元素都转成字符串,而真正接收到的只有服务端发来的几个字符
stringstrMsgRec=System.Text.Encoding.UTF8.GetString(arrMsgRec,1,length-1);
ShowMsg(strMsgRec);
elseif(arrMsgRec[0]==1)//如果是1,则代表发送过来的是文件数据(图片/视频/文件....)
SaveFileDialogsfd=newSaveFileDialog();
//保存文件选择框对象
if(sfd.ShowDialog()==System.Windows.Forms.DialogResult.OK)//用户选择文件路径后
stringfileSavePath=sfd.FileName;
//获得要保存的文件路径
//创建文件流,然后让文件流来根据路径创建一个文件
using(FileStreamfs=newFileStream(fileSavePath,FileMode.Create))
fs.Write(arrMsgRec,1,length-1);
文件保存成功:
+fileSavePath);
//发送消息到客户端
privatevoidbtnSend_Click(objectsender,EventArgse)
if(string.IsNullOrEmpty(lbOnline.Text))
MessageBox.Show("
请选择要发送的好友"
else
stringstrMsg=txtMsgSend.Text.Trim();
//将要发送的字符串转成utf8对应的字节数组
byte[]arrMsg=System.Text.Encoding.UTF8.GetBytes(strMsg);
//获得列表中选中的KEY
stringstrClientKey=lbOnline.Text;
//通过key,找到字典集合中对应的与某个客户端通信的套接字的send方法,发送数据给对方
dict[strClientKey].Send(arrMsg);
//sokConnection.Send(arrMsg);
发送了数据出去:
+strMsg);
发送时异常:
+ex.Message);
//服务端群发消息
privatevoidbtnSendToAll_Click(objectsender,EventArgse)
foreach(Socketsindict.Values)
s.Send(arrMsg);
群发完毕!
:
)"
#region显示消息
///显示消息
paramname="
msg"
>
<
/param>
voidShowMsg(stringmsg)
∙客户端:
申请一个socket(socketClient)
连接服务器(指明IP地址和端口号)
namespaceMyChatRoomClient