-
C#
菜鸟做这个东东竟然花了快三天的时间了,真是菜,菜,菜~~~<
/p>
下面是我用
C#
写的
一个简单的
TCP
通信,主要的
功能有:
(
1
)
多个客户端与服务器间的数据交流
(
2
)可以实现群发的功能
(
3
)客户端与服务端可以进行文件的传输
主要用到的知识:
TCP
里的
socket
、
、
、
多线程
Thread
、
、
、
下面的是界面:
下面分别是服务端和客户端的代码
,如若借用,请标明出处
~~~
服务端代码:
[csharp]
view plaincopyprint?
using System;
using c;
using entModel;
using
using g;
using
using
using
using s;
using //
IP
,
IPAddress,
IPEndPoint
,端口等;
using ing;
using
;
namespace
_11111
{
public partial class frm_server : Form
{
public frm_server()
{
InitializeComponent();
orIllegalCrossThreadCalls = false;
}
Thread threadWatch = null; //
负责监听客户端连接请求的
线程;
Socket socketWatch = null;
Dictionary
Dictionary
private void
btnBeginListen_Click(object sender, EventArgs e)
{
//
创建负责监听的套接字,注意其中的参数;
socketWatch = new
Socket(etwork, , );
//
获得文本框中的
IP
对象;
IPAddress address =
(());
//
创建包含
ip
和端口号的网络节点对象;
IPEndPoint endPoint = new
IPEndPoint(address, (()));
try
{
//
将负责监听的套接字绑定到唯
一的
ip
和端口上;
(endPoint);
}
catch
(SocketException se)
{
(
异常:
return;
}
//
设置监听队列的长度;
(10);
//
创建负责监听的线程;
threadWatch = new
Thread(WatchConnecting);
ground = true;
();
ShowMsg(
服务器启动监听成功!
//}
}
///
///
监听客户端请求的方法;
///
void WatchConnecting()
{
while (true)
//
持续不断的监听客户端的连接请求;
{
//
开始监听客户端连接请求,
Accept
方法会阻断当前的线程;
Socket sokConnection = (); //
一旦监听到一个客户端的请求,就返回一个
与该客户端通信的
套接字;
//
想列表控件中添加客户端的
IP
信息;
(ng());
//
将与客户端连接的
套接字
对象添加到集合中;
(ng(), sokConnection);
ShowMsg(
客户端连接成功!
Thread thr = new Thread(RecMsg);
ground = true;
(sokConnection);
(ng(),
thr);
//
将新建的线程
添加
到线
程的集合中去。
}
}
void
RecMsg(object sokConnectionparn)
{
Socket
sokClient = sokConnectionparn as Socket;
while (true)
{
//
定义一个
2M
的缓存区;
byte[] arrMsgRec = new
byte[1024 * 1024 * 2];
//
将接受到的数据存入到输入
arrMsgRec
中;
int length = -1;
try
{
length =
e(arrMsgRec); //
接收数据,并返回数据的长度;
}
catch
(SocketException se)
{
ShowMsg(
异常:
//
从
通信套接字
集合中删除被中断连接的通信套接字;
(ng());
//
从通信线程集合中删除被中断连接的通信线程对象;
(ng());
//
从列表中移除被中断的连接
IP
(ng());
break;
}
catch (Exception e)
{
Sh
owMsg(
异常:
//
从
通信套接字
集合中删除被中断连接的通信套接字;
(ng());
//
从通信线程集合中删除被中断连接的通信线程对象;
(ng());
//
从列表中移除被中断的连接
IP
(ng());
break;
}
if (arrMsgRec[0] == 0) //
表示接收到的是数据;
{
string strMsg
= ing(arrMsgRec,1, length-1);//
将接受到的字
节数据转化成字符串;
ShowMsg(strMsg);
}
if
(arrMsgRec[0] == 1) //
表示接收到的是文件;
{
SaveFileDialog
sfd = new SaveFileDialog();
if (alog(this) == )
{//
在上边的
alog
()
的括号里边一定要加上
this
否则就不会弹出
另存为
的
对
话框,而弹出的是本类的其他窗口,
,这个一定要注意!
!
p>
!
【解释:加了
this
< br>的
alog(this)
,
“<
/p>
另存为
”
窗口的指针才能被
SaveFileDialog
的对象调用,若不加
thisSaveFileDialog
的对象调用的是本类的其他窗口了,当然不弹
出
“
另存为
”
窗口。
】
string fileSavePath = me;//
获得文件保存的路径;
//
创建文件流,然后根据路径创建文件;
using (FileStream fs = new
FileStream(fileSavePath, ))
{
(arrMsgRec, 1,
length - 1);
ShowMsg(
文件保存成功:
}
}
}
}
}
void
ShowMsg(string str)
{
Text(str +
}
//
发送消息
private void btnSend_Click(object
sender, EventArgs e)
{
string strMsg =
服务器
byte[]
arrMsg
=
es(strMsg);
//
将要
发送的字符串转换成
Utf-8
字节数组;
byte[] arrSendMsg=new
byte[+1];
arrSendMsg[0] =
0; //
表示发送的是消息数据
opy(arrMsg, 0, arrSendMsg, 1, );
string strKey =
strKey = ();
if
(OrEmpty(strKey)) //
判断是不是选择了发送的对象;
{
(
请选
择你要发送的好友!
!
!
}
else
{
dict[strKey].Send(arrSendMsg);//
解决了
sokConnection
是局部变量,
不能再本函数中引用的
问
题;
ShowMsg(strMsg);
();
}
}
///
///
群发消息
///
///
///
消息
private void btnSendToAll_Click(object
sender, EventArgs e)
{
string strMsg =
服务器
byte[]
arrMsg
=
es(strMsg);
//
将要
发送的字符串转换成
Utf-8
字节数组;
using System;
using c;
using entModel;
using
using g;
using
using
using
using s;
using
//
IP
,
IPAddress,
IPEndPoint
,端口等;
using ing;
using
namespace _11111
{
public partial class
frm_server : Form
{
public frm_server()
{
InitializeComponent();
orIllegalCrossThreadCalls = false;
}
Thread
threadWatch = null; //
负责监听客户端连接请求的
线程;
Socket
socketWatch = null;
Dictionary
Dictionary
private void
btnBeginListen_Click(object sender, EventArgs e)
{
//
创建负责监听的套接字,注意其中的参数;
socketWatch
=
new
Socket(etwork,
,
);
//
获得文本框中的
IP
对象;
IPAddress address = (());
//
创建包含
ip
和端口号的网络节点对象
;
IPEndPoint
endPoint
=
new
IPEndPoint(address,
(()));
try
{
//
将
负责监听的套接字绑定到唯一的
ip
和端口上;
(endPoint);
}
catch (SocketException se)
{
(
异常:
return;
}
//
设置监听队列的长度;
(10);
//
创建负责监听的线程;
threadWatch = new
Thread(WatchConnecting);
ground = true;
();
ShowMsg(
服务器启动监听成
功!
//}
}
///
///
监听客户端请求的方法;
///
void WatchConnecting()
{
while (true)
//
持续不断的监听客户端的连接请求;
{
//
开始监听客户端连接请求,
Ac
cept
方法会阻断当前的线程;
Socket sokConnection = (); //
一旦监听到一个客户端的
请求,就返回一个与该客户端通信的
套接字;
//
想列表控件中添加客户端的
IP
信息;
(ng());
//
将与客户端连接的
套接字
对象添加到集合中;
(ng(), sokConnection);
Sho
wMsg(
客户端连接成功!
Thread thr = new Thread(RecMsg);
ground = true;
(sokConnection);
(ng(),
thr);
//
将新
建的线程
添加
到线程的集合中去。
}
}
void
RecMsg(object sokConnectionparn)
{
Socket sokClient = sokConnectionparn as
Socket;
while (true)
{
//
定义一个
2M
< br>的缓存区;
byte[]
arrMsgRec = new byte[1024 * 1024 * 2];
//
将接受到的数据存入到输入
arrMsgRec
中;
int length = -1;
try
{
length = e(arrMsgRec); //
接收数据,并返回数据
的长度;
}
catch (SocketException se)
{
ShowMsg(
异常:
//
从
通信套接字
集合中删除被中断连接的通信套接字;
(ng());
//
从通信线程集合中删除被中断连接的通信线程对象;
(ng());
//
从列表中移除被中断的连接
IP
(ng());
break;
}
catch (Exception e)
{
ShowMsg(
异常:
//
从
通信套接字
集合中删除被中断连接的通信套接字;
(ng());
//
从通信线程集合中删除被中断连接的通信线程对象;
(ng());
//
从列表中移除被中断的连接
IP
(ng());
break;
}
if (arrMsgRec[0] == 0)
//
表示接收到的是数据;
{
string
strMsg
=
ing(arrMsgRec,1,
length-1);//
将接受到的字节数据转化成
字符串;
ShowMsg(strMsg);
}
if (arrMsgRec[0] == 1) //
表示接收到的是文件;
{
SaveFileDialog sfd = new
SaveFileDialog();
if
(alog(this)
==
)
{//
在上边的
alog
()
的括号里边一定要加上
this
否则就不会弹出
另存为
的对话框,
< br>而弹出的是本类的其他窗口,
,
这个一定要注意!
!
!
【解释:加了
t
his
的
alog(this)
,
p>
“
另存为
”
窗口的
指针才能被
SaveFileDialog
的对
象调用,
若不加
thisSaveFileDialo
g
的对象调用的是本类的其他窗口了,
当然不弹出
“
另存为
”
窗口。
】
string
fileSavePath = me;//
获得文件保存的路
径;
//
创建文件流,然后根据路径创建文件;
using
(FileStream
fs
=
new
FileStream(fileSavePath,
))
{
(arrMsgRec, 1, length - 1);
p>
ShowMsg(
文件保存成功:
}
}
}
}
}
void ShowMsg(string str)
{
Text(str +
}
//
发送消息
private void btnSend_Click(object
sender, EventArgs e)
{
string strMsg =
服务器
-->
byte[] arrMsg = es(strMsg);
//
将要发送的字
符串转换成
Utf
-8
字节数组;
byte[] arrSendMsg=new byte[+1];
arrSendMsg[0] = 0; //
表示发送的是消息数据
opy(arrMsg, 0, arrSendMsg, 1, );
string strKey =
strKey = ();
if (OrEmpty(strKey))
//
判断是不是选择了发送的对象;
{
p>
(
请选择你要发送的好友!
!
!
}
else
{
dict[strKey].Send(arrSendMsg);//
解决了
sokConnection
是局部变量,
不能
再本函数中引用的问
题;
ShowMsg(strMsg);
();
}
}
///
///
群发消息
///
///
///
消息
private void btnSendToAll_Click(object
sender, EventArgs e)
{
string strMsg =
服务器
-->
byte[] arrMsg = es(strMsg);
//
将要发送的字
符串转换成
Utf
-8
字节数组;
[csharp]
view plaincopyprint?
[csharp] view plaincopyprint?
上次写的
时
候把这一段给弄掉了,
实在是抱歉哈
~
用来标识发送是数据而不是文件,
如果没有这一段
的客户端就
接收不到消息了
~~~
arrSendMsg[0] = 0; //
表示发送的是消息数据
opy(arrMsg, 0, arrSendMsg, 1, );
byte[] arrSendMsg = new
byte[ + 1]; //
上次写的时候把这一段给
弄掉
了,
实在是抱歉哈
~
用来标识发送是
数据而不是文件,
如果没有这一段的客户端就接收
不到消息了<
/p>
~~~
arrSendMsg[0] = 0; //
表示发送的是消息数据
opy(arrMsg, 0, arrSendMsg, 1, );
[csharp] view plaincopyprint?
foreach (Socket s in )
{
(arrMsg);
}
ShowMsg(strMsg);
();
ShowMsg(
群发完毕~~~
}
//
选择要发送的文件
private void
btnSelectFile_Click_1(object sender, EventArgs e)
{
OpenFileDialog ofd = new
OpenFileDialog();
lDirectory =
if
(alog() == )
{
= me;
}
}
//
文件的发送
private void
btnSendFile_Click_1(object sender, EventArgs e)
{
if
(OrEmpty())
{
<
/p>
(
请选择你要发送的文件!
!
!
-
-
-
-
-
-
-
-
-
上一篇:设备台账标准格式
下一篇:6MW背压机运行规程