-
C#
菜鸟做这个东东竟然花了快三天的时间了
,真是菜,菜,菜?
F
面是我用
p>
C#
写的一个简单的
TCP
通信,主要的功能有
:
(1)
多个客户端与服务器间的数据交流
(2)
可以实现群发的功能
(3
)
客户端与服务端可以进行文件的传输
主要用到的知识:
TCP
里的
socket
、、
多线程
Thread
、、
F
面的是界面:
口
-
孤天弱容户揣
昵称:雪
连接服势端
发送消息
选择文件
岌送文件
J
鞭天宣底服努蔬
IF
|
昌<
/p>
I
回
|
0
J
S-1
S-.
S-.
s
畫
盏
成
而
成
山
p>
成
雷
成
而
成
成
户
成
户
p>
而
户
山
而
172.16
12.12
FOK
S068
T
:
在线列表
172.16.12.12:58063
172.
16.12.12:58064
17
2.
IB.
12.12:56065
1T2. 16.12.12:58066
1T2.
IB.
12.12:58067
172.
15.12.12:56068
172.10.
12.12:58069
1T2.
16.12.12
56OT0
选择文件
下面分别是服务端和客户端的代码,如若借用,请标明出处
服务端代码:
[csharp]
view pla in copypri nt?
using System;
using t ion neric;
using
onen tModel;
using
using
ing;
using
using
using
using s;
usi ng //IP
,
IPAddress, IPE ndPoi
nt
,端口等
;
using
ing;
using Syste
n
amespace _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)
{
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
否则就不会弹出
另存为
的
对话框,而弹
出的是本类的其他窗口,
,这个一定要注意!
!!【解释:加了
this
的
alog(this)
,
“另存为
”窗口的指针才能被
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) //
持续不断的监听客户端的连接请求;
{
//
开始监听客户端连接请求,
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)
{
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
否则就不会弹出
另存为
的对话框,
而弹出的是本类的其他窗口,
,这个一定要注意!
!!
【解释:加了
this
的
alog(this)
,
“另存为
”窗口的指针才能被
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
字节数组;
[csharp] view plaincopyprint?
[csharp] view plaincopyprint?
上次写的
时候把
这一段给弄掉了,
实在是抱歉哈
~
用来标识发送是数据而不是文件,
如果没有这一段
的客户端就接
收不到消息了
~~~
arrSendMsg[0] = 0; //
表示发送的是消息数据
opy(arrMsg, 0, arrSendMsg, 1, );
byte[] arrSendMsg = new byte[ + 1]; //
上次写的时候把这一段给
弄掉
了,
实在是抱歉哈
~
用来标识发送是数据而不是文件,
如果没有这一段的客户端就接收
不到消息了
~~~
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())
{
(
请选择你要发送的文件!
!!
;
}
else
{
//
用文件流打开用户要发送的文件;
using (FileStream fs = new FileStream(,
))
{
string
fileName=eName();
string
fileExtension=ension();
string strMsg =
我给你发送的文件为:
byte[] arrMsg = es(strMsg);
//
将要发送的字符串转换成
Utf-8
字节
数组;
byte[] arrSendMsg = new byte[ + 1];
arrSendMsg[0] = 0; //
表示发送的是消息数据
opy(arrMsg, 0, arrSendMsg, 1, );
bool fff = true;
-
-
-
-
-
-
-
-
-
上一篇:北电PBX程控电话交换机基本操作命令
下一篇:水位计说明书