#1楼 得分:0 回复于:2008-06-23 08:27:19
C# code
///
线程执行体,转发消息
///
</summary>
///
<param name="obj">
传递给线程执行体的用户名,用以与用户通信
</param>
private
void
ThreadFunc(
object
obj)
{
//
通过转发表得到当前用户套接字
Socket clientSkt
=
_transmit_tb[obj]
as
Socket;
//
主循环
while
(
true
)
{
try
{
//
接受第一个数据包。
//
由于程序逻辑结构简单,所以在这里对客户机发送的第一个包内容作逐一判断,
//
这里的实现不够优雅,但不失为此简单模型的一个解决之道。
byte
[] packetBuff
=
new
byte
[_maxPacket];
clientSkt.Receive(packetBuff);
string
_str
=
Encoding.Unicode.GetString(packetBuff).TrimEnd(
'
/0
'
);
//
如果是发给不在线好友的信息
if
(_str.StartsWith(
"
cmd::FriendMessage
"
))
{
string
UserName
=
_str.Substring(
"
cmd::FriendMessage
"
.Length,
20
).Trim();
string
MessageS
=
_str.Substring(
"
cmd::FriendMessage
"
.Length
+
20
, _str.Length
-
"
cmd::FriendMessage
"
.Length
-
20
);
SaveMessage(obj
as
string
, UserName, MessageS);
continue
;
}
//
如果是离线请求
if
(_str.StartsWith(
"
cmd::RequestLogout
"
))
{
_transmit_tb.Remove(obj);
UpdateFriendList((
string
)obj,
false
,
""
);
//
string svrlog = string.Format("[系统消息]用户 {0} 在 {1} 已断开... 当前在线人数: {2}/r/n/r/n", obj, DateTime.Now, _transmit_tb.Count);
//
Console.WriteLine(svrlog);
//
向所有客户机发送系统消息
//
foreach (DictionaryEntry de in _transmit_tb)
//
{
//
string _clientName = de.Key as string;
//
Socket _clientSkt = de.Value as Socket;
//
_clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));
//
}
Thread.CurrentThread.Abort();
}
//
如果是请求好友列表
if
(_str.StartsWith(
"
cmd::RequestFriendList
"
))
{
SerializeFriendList(obj, clientSkt);
//
将该用户不在线时的信息发送给用户
DataTable TabMessage
=
ReadMessage(obj
as
string
);
if
(TabMessage
!=
null
)
{
foreach
(DataRow myrow
in
TabMessage.Rows)
{
if
(myrow[
"
SendUserName
"
].ToString()
==
"
System::Message
"
)
{
clientSkt.Send(Encoding.Unicode.GetBytes(myrow[
"
Message
"
].ToString()));
}
else
{
clientSkt.Send(Encoding.Unicode.GetBytes(
"
cmd::FriendMessage
"
+
myrow[
"
SendUserName
"
].ToString().PadRight(
20
,
'
'
)
+
myrow[
"
Message
"
].ToString()));
}
}
}
//
这里不需要再继续接受后继数据包了,跳出当前循环体。
continue
;
}
///
/如果是请求好友列表
//
if (_str.StartsWith("cmd::RequestOnLineList"))
//
{
//
byte[] onlineBuff = SerializeOnlineList();
//
//
先发送响应信号,用户客户机的判断
//
clientSkt.Send(Encoding.Unicode.GetBytes("cmd::RequestOnLineList"));
//
clientSkt.Send(onlineBuff);
//
//
这里不需要再继续接受后继数据包了,跳出当前循环体。
//
continue;
//
}
//
查找用户
if
(_str.StartsWith(
"
Find::FindFriend
"
))
{
DataTable TabFind
=
TabUser.Clone();
DataRow [] FindRow
=
null
;
string
UserName
=
_str.Substring(
"
Find::FindFriend
"
.Length, _str.Length
-
"
Find::FindFriend
"
.Length);
if
(UserName.Equals(
"
Find::WhoOnLine
"
))
{
//
看谁在线
FindRow
=
TabUser.Select(
"
ZX = 1
"
);
}
else
//
精确查找
{
FindRow
=
TabUser.Select(
"
UserName = '
"
+
UserName
+
"
'
"
);
}
foreach
(DataRow myrow
in
FindRow)
{
TabFind.ImportRow(myrow);
}
clientSkt.Send(Encoding.Unicode.GetBytes(
"
Find::FindFriend
"
));
IFormatter format
=
new
BinaryFormatter();
MemoryStream stream
=
new
MemoryStream();
format.Serialize(stream, TabFind);
stream.Position
=
0
;
byte
[] ret
=
new
byte
[_maxPacket];
int
count
=
0
;
count
=
stream.Read(ret,
0
, _maxPacket);
while
(count
>
0
)
{
clientSkt.Send(ret);
count
=
stream.Read(ret,
0
, _maxPacket);
}
clientSkt.Send(Encoding.Unicode.GetBytes(
"
Find::FindFriendEnd
"
));
stream.Close();
TabFind
=
null
;
FindRow
=
null
;
//
这里不需要再继续接受后继数据包了,跳出当前循环体。
continue
;
}
//
请求添加好友
if
(_str.StartsWith(
"
Find::AddFriendAsk
"
))
{
string
UserName
=
_str.Substring(
"
Find::AddFriendAsk
"
.Length, _str.Length
-
"
Find::AddFriendAsk
"
.Length);
//
通过转发表查找接收方的套接字
if
(_transmit_tb.Count
!=
0
&&
_transmit_tb.ContainsKey(UserName))
{
Socket receiverSkt
=
_transmit_tb[UserName]
as
Socket;
receiverSkt.Send(Encoding.Unicode.GetBytes(
"
Find::AddFriendAsk
"
+
obj
as
string
));
}
//
这里不需要再继续接受后继数据包了,跳出当前循环体。
continue
;
}
//
回复答应添加好友
if
(_str.StartsWith(
"
Find::AddFriendYes
"
))
{
string
UserName
=
_str.Substring(
"
Find::AddFriendYes
"
.Length, _str.Length
-
"
Find::AddFriendYes
"
.Length);
///
/ 保存数据
DataTable TabmyFriend
=
new
DataTable() ;
//
保存该用户
TabmyFriend.ReadXml(MyPath
+
"
//UserFriend//
"
+
obj
as
string
+
"
.xml
"
);
DataRow newRow
=
TabmyFriend.NewRow();
newRow[
"
UserName
"
]
=
UserName;
TabmyFriend.Rows.Add(newRow);
TabmyFriend.WriteXml(MyPath
+
"
//UserFriend//
"
+
obj
as
string
+
"
.xml
"
, XmlWriteMode.WriteSchema,
false
);
//
保存其好友
TabmyFriend
=
new
DataTable();
TabmyFriend.ReadXml(MyPath
+
"
//UserFriend//
"
+
UserName
+
"
.xml
"
);
DataRow newRow1
=
TabmyFriend.NewRow();
newRow1[
"
UserName
"
]
=
obj
as
string
;
TabmyFriend.Rows.Add(newRow1);
TabmyFriend.WriteXml(MyPath
+
"
//UserFriend//
"
+
UserName
+
"
.xml
"
, XmlWriteMode.WriteSchema,
false
);
TabmyFriend
=
null
;
SerializeFriendList(obj, clientSkt);
#2楼 得分:0 回复于:2008-06-23 08:32:35
C# code
//
"开始"按钮事件
private
void
button1_Click(
object
sender, System.EventArgs e) {
//
取得预保存的文件名
string
fileName
=
textBox3.Text.Trim();
//
远程主机
string
hostName
=
textBox1.Text.Trim();
//
端口
int
port
=
Int32.Parse(textBox2.Text.Trim());
//
得到主机信息
IPHostEntry ipInfo
=
Dns.GetHostByName(hostName);
//
取得IPAddress[]
IPAddress[] ipAddr
=
ipInfo.AddressList;
//
得到ip
IPAddress ip
=
ipAddr[
0
];
//
组合出远程终结点
IPEndPoint hostEP
=
new
IPEndPoint(ip,port);
//
创建Socket 实例
Socket socket
=
new
Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
try
{
//
尝试连接
socket.Connect(hostEP);
}
catch
(Exception se)
{
MessageBox.Show(
"
连接错误
"
+
se.Message,
"
提示信息
,MessageBoxButtons.RetryCancel,MessageBoxIcon.Information);
}
//
发送给远程主机的请求内容串
string
sendStr
=
"
GET / HTTP/1.1/r/nHost:
"
+
hostName
+
"
/r/nConnection: Close/r/n/r/n
"
;
//
创建bytes字节数组以转换发送串
byte
[] bytesSendStr
=
new
byte
[
1024
];
//
将发送内容字符串转换成字节byte数组
bytesSendStr
=
Encoding.ASCII.GetBytes(sendStr);
try
{
//
向主机发送请求
socket.Send(bytesSendStr,bytesSendStr.Length,
0
);
}
catch
(Exception ce)
{
MessageBox.Show(
"
发送错误:
"
+
ce.Message,
"
提示信息
,MessageBoxButtons.RetryCancel,MessageBoxIcon.Information);
}
//
声明接收返回内容的字符串
string
recvStr
=
""
;
//
声明字节数组,一次接收数据的长度为1024字节
byte
[] recvBytes
=
new
byte
[
1024
];
//
返回实际接收内容的字节数
int
bytes
=
0
;
//
循环读取,直到接收完所有数据
while
(
true
)
{
bytes
=
socket.Receive(recvBytes,recvBytes.Length,
0
);
//
读取完成后退出循环
if
(bytes〈
=
0
)
break
;
//
将读取的字节数转换为字符串
recvStr
+=
Encoding.ASCII.GetString(recvBytes,
0
,bytes);
}
//
将所读取的字符串转换为字节数组
byte
[] content
=
Encoding.ASCII.GetBytes(recvStr);
try
{
//
创建文件流对象实例
FileStream fs
=
new
FileStream(fileName,FileMode.OpenOrCreate,FileAccess.ReadWrite);
//
写入文件
fs.Write(content,
0
,content.Length);
}
catch
(Exception fe)
{
MessageBox.Show(
"
文件创建/写入错误:
"
+
fe.Message,
"
提示信息
"
,MessageBoxButtons.RetryCancel,MessageBoxIcon.Information);
}
//
禁用Socket
socket.Shutdown(SocketShutdown.Both);
//
关闭Socket
socket.Close();
}
}
#3楼 得分:1 回复于:2008-06-23 08:34:48
#4楼 得分:0 回复于:2008-06-23 08:35:48
TCP/UDP通讯
UDP的:
C# code
namespace
UDPServer
{
class
Program
{
static
void
Main(
string
[] args)
{
int
recv;
byte
[] data
=
new
byte
[
1024
];
//
构建TCP 服务器
//
得到本机IP,设置TCP端口号
IPEndPoint ipep
=
new
IPEndPoint(IPAddress.Any ,
8001
);
Socket newsock
=
new
Socket(AddressFamily.InterNetwork, SocketType.Dgram , ProtocolType.Udp);
//
绑定网络地址
newsock.Bind(ipep);
Console.WriteLine(
"
This is a Server, host name is {0}
"
,Dns.GetHostName());
//
等待客户机连接
Console.WriteLine(
"
Waiting for a client...
"
);
//
得到客户机IP
IPEndPoint sender
=
new
IPEndPoint(IPAddress.Any,
0
);
EndPoint Remote
=
(EndPoint)(sender);
recv
=
newsock.ReceiveFrom(data,
ref
Remote);
Console .WriteLine (
"
Message received from {0}:
"
, Remote.ToString ());
Console .WriteLine (Encoding .ASCII .GetString (data ,
0
,recv ));
//
客户机连接成功后,发送欢迎信息
string
welcome
=
"
Welcome !
"
;
//
字符串与字节数组相互转换
data
=
Encoding .ASCII .GetBytes (welcome );
//
发送信息
newsock .SendTo (data ,data.Length ,SocketFlags .None ,Remote );
while
(
true
)
{
data
=
new
byte
[
1024
];
//
发送接受信息
recv
=
newsock.ReceiveFrom(data ,
ref
Remote);
Console .WriteLine (Encoding .ASCII .GetString (data ,
0
,recv));
newsock .SendTo (data ,recv ,SocketFlags .None ,Remote );
}
}
}
}
C# code
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Net;
using
System.Net.Sockets;
namespace
UDPClient
{
class
Program
{
static
void
Main(
string
[] args)
{
byte
[] data
=
new
byte
[
1024
];
string
input ,stringData;
//
构建TCP 服务器
Console.WriteLine(
"
This is a Client, host name is {0}
"
, Dns.GetHostName());
//
设置服务IP,设置TCP端口号
IPEndPoint ipep
=
new
IPEndPoint(IPAddress .Parse (
"
127.0.0.1
"
) ,
8001
);
//
定义网络类型,数据连接类型和网络协议UDP
Socket server
=
new
Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string
welcome
=
"
Hello!
"
;
data
=
Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, ipep);
IPEndPoint sender
=
new
IPEndPoint(IPAddress.Any,
0
);
EndPoint Remote
=
(EndPoint)sender;
data
=
new
byte
[
1024
];
int
recv
=
server.ReceiveFrom(data,
ref
Remote);
Console.WriteLine(
"
Message received from {0}:
"
, Remote.ToString());
Console.WriteLine(Encoding .ASCII .GetString (data,
0
,recv));
while
(
true
)
{
input
=
Console .ReadLine ();
if
(input
==
"
exit
"
)
break
;
server .SendTo (Encoding .ASCII .GetBytes (input ),Remote );
data
=
new
byte
[
1024
];
recv
=
server.ReceiveFrom(data,
ref
Remote);
stringData
=
Encoding.ASCII.GetString(data,
0
, recv);
Console.WriteLine(stringData);
}
Console .WriteLine (
"
Stopping Client.
"
);
server .Close ();
}
}
}
简单的UDP
C# code
try
{
Socket s
=
new
Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//
向此网段发广播包
int
UDPListenerPort
=
8082
;
IPAddress broadcast
=
IPAddress.Parse(
"
192.168.0.255
"
);
//
此处根据IP及子网掩码改为相应的广播IP
string
ts
=
"
This is UPD string for sending
"
;
byte
[] sendbuf
=
Encoding.ASCII.GetBytes(ts);
IPEndPoint ep
=
new
IPEndPoint(broadcast, UDPListenerPort);
s.SendTo(sendbuf, ep);
}
catch
(Exception e)
{}
C# code
UdpClient listener;
int
UDPListenerPort
=
8082
;
IPEndPoint groupEP
=
new
IPEndPoint(IPAddress.Any, UDPListenerPort);
try
{
while
(
true
)
{
byte
[] bytes
=
listener.Receive(
ref
groupEP);
string
RecIP
=
groupEP.ToString().Substring(
0
, groupEP.ToString().IndexOf(
"
:
"
));
//
收到发送UPD端的IP
string
RecStr
=
Encoding.ASCII.GetString(bytes,
0
, bytes.Length);
//
收到的UPD字符串
}
}
catch
{}
#5楼 得分:1 回复于:2008-06-23 08:36:10
引用 2 楼 sjm2003 的回复:
C# code//"开始"按钮事件
private void button1_Click(object sender, System.EventArgs e) {
//取得预保存的文件名
string fileName=textBox3.Text.Trim();
//远程主机
string hostName=textBox1.Text.Trim();
//端口
int port=Int32.Parse(textBox2.Text.Trim());
//得到主机信息
IPHostEntry ipInfo=Dns.GetHostByName(hostName);
//取得IPAddress[]
…
沙发 学习
#6楼 得分:1 回复于:2008-06-23 08:39:02
[size=12px][/size][size=12px][/size]帮顶![size=12px][/size]
#7楼 得分:0 回复于:2008-06-23 08:41:23
C#UDP的多路广播组的发送和接收
下列范例使用 UdpClient,在通讯端口11000传送UDP 资料包至多点传送位址群组 224.268.100.2。它传送命令列上指定的信息字串。
C# code
using
System;
using
System.Net;
using
System.Net.Sockets;
using
System.Text;
public
class
UDPMulticastSender {
private
static
IPAddress GroupAddress
=
IPAddress.Parse(
"
224.168.100.2
"
);
private
static
int
GroupPort
=
11000
;
private
static
void
Send( String message) {
UdpClient sender
=
new
UdpClient();
IPEndPoint groupEP
=
new
IPEndPoint(GroupAddress,GroupPort);
try
{
Console.WriteLine(
"
Sending datagram : {0}
"
, message);
byte
[] bytes
=
Encoding.ASCII.GetBytes(message);
sender.Send(bytes, bytes.Length, groupEP);
sender.Close();
}
catch
(Exception e) {
Console.WriteLine(e.ToString());
}
}
public
static
int
Main(String[] args) {
Send(args[
0
]);
return
0
;
}
}
C# code
using
System;
using
System.Net;
using
System.Net.Sockets;
using
System.Text;
public
class
UDPMulticastListener {
private
static
readonly
IPAddress GroupAddress
=
IPAddress.Parse(
"
224.168.100.2
"
);
private
const
int
GroupPort
=
11000
;
private
static
void
StartListener() {
bool
done
=
false
;
UdpClient listener
=
new
UdpClient();
IPEndPoint groupEP
=
new
IPEndPoint(GroupAddress,GroupPort);
try
{
listener.JoinMulticastGroup(GroupAddress);
listener.Connect(groupEP);
while
(
!
done) {
Console.WriteLine(
"
Waiting for broadcast
"
);
byte
[] bytes
=
listener.Receive(
ref
groupEP);
Console.WriteLine(
"
Received broadcast from {0} :/n {1}/n
"
,
groupEP.ToString(),
Encoding.ASCII.GetString(bytes,
0
,bytes.Length));
}
listener.Close();
}
catch
(Exception e) {
Console.WriteLine(e.ToString());
}
}
public
static
int
Main(String[] args) {
StartListener();
return
0
;
}
}
#8楼 得分:0 回复于:2008-06-23 08:44:39
C#TCP的:
C# code
TCPClient
TCPClient 类提供了一种使用 TCP 协议连接到某个端点的简化方法。它还通过 NetworkStream 对象展现在连接过程中读取或写入的数据。请参见下面从 QuickStart 文档中摘录的日期
/
时间客户机示例。
使用 C# 编写
using
System;
using
System.Net;
using
System.Net.Sockets;
using
System.IO;
using
System.Text;
class
Client
{
public
static
void
Main(String[] args)
{
TCPClient tcpc
=
new
TCPClient();
Byte[] read
=
new
Byte[
32
];
if
(args.Length
!=
1
)
{
Console.WriteLine(“请在命令行中指定服务器名称”);
return
;
}
String server
=
args[
0
];
//
验证服务器是否存在
if
(DNS.GetHostByName(server)
==
null
)
{
Console.WriteLine(“找不到服务器:”
+
服务器);
return
;
}
//
尝试连接到服务器
if
(tcpc.Connect(server,
13
)
==
-
1
)
{
Console.WriteLine(“无法连接到服务器:”
+
服务器);
return
;
}
//
获取流
Stream s
=
tcpc.GetStream();
//
读取流并将它转换为 ASCII 码形式
int
bytes
=
s.Read(read,
0
, read.Length);
String Time
=
Encoding.ASCII.GetString(read);
//
显示数据
Console.WriteLine(“已接收到的”
+
字节
+
“字节”);
Console.WriteLine(“当前日期和时间是:”
+
时间);
tcpc.Close();
}
}
TCPListener
TCPListener 类便于在来自某个客户机的 TCP 连接的特定套接字上进行侦听的工作。请参见下面包括在 QuickStart 文档中的日期
/
时间服务器示例。
使用 C# 编写
using
System;
using
System.Net;
using
System.Net.Sockets;
using
System.Text;
class
Server
{
public
static
void
Main()
{
DateTime now;
String strDateLine;
Encoding ASCII
=
Encoding.ASCII;
//
在端口 13 进行侦听
TCPListener tcpl
=
new
TCPListener(
13
);
tcpl.Start();
Console.WriteLine(“正在等待客户进行连接”);
Console.WriteLine(“请按 Ctrl
+
c 退出...”);
while
(
true
)
{
//
接收会阻塞,直到有人连接上
Socket s
=
tcpl.Accept();
//
获取当前的日期和时间并将它连接成一个字符串
now
=
DateTime.Now;
strDateLine
=
now.ToShortDateString()
+
"
"
+
now.ToLongTimeString();
//
将该字符串转换成一个字节数组并发送它
Byte[] byteDateLine
=
ASCII.GetBytes(strDateLine.ToCharArray());
s.Send(byteDateLine, byteDateLine.Length,
0
);
Console.WriteLine(“发送”
+
strDateLine);
}
}
}
#9楼 得分:1 回复于:2008-06-23 08:46:02
不错,辛苦了
顺便问下大哥,能否推荐下学习网络通讯编程的书籍,谢谢了,呵呵
#10楼 得分:0 回复于:2008-06-23 08:47:44
这个似乎是FTP下载的:
C# code
#region
"Download: File transfer FROM ftp server"
///
<summary>
///
Copy a file from FTP server to local
///
</summary>
///
<param name="sourceFilename">
Target filename, if required
</param>
///
<param name="localFilename">
Full path of the local file
</param>
///
<returns>
</returns>
///
<remarks>
Target can be blank (use same filename), or just a filename
///
(assumes current directory) or a full path and filename
</remarks>
public
bool
Download(
string
sourceFilename,
string
localFilename,
bool
PermitOverwrite)
{
//
2. determine target file
FileInfo fi
=
new
FileInfo(localFilename);
return
this
.Download(sourceFilename, fi, PermitOverwrite);
}
//
Version taking an FtpFileInfo
public
bool
Download(FtpFileInfo file,
string
localFilename,
bool
permitOverwrite)
{
return
this
.Download(file.FullName, localFilename, permitOverwrite);
}
//
Another version taking FtpFileInfo and FileInfo
public
bool
Download(FtpFileInfo file, FileInfo localFI,
bool
permitOverwrite)
{
return
this
.Download(file.FullName, localFI, permitOverwrite);
}
//
Version taking string/FileInfo
public
bool
Download(
string
sourceFilename, FileInfo targetFI,
bool
permitOverwrite)
{
//
1. check target
if
(targetFI.Exists
&&
!
(permitOverwrite))
{
throw
(
new
ApplicationException(
"
Target file already exists
"
));
}
//
2. check source
string
target;
if
(sourceFilename.Trim()
==
""
)
{
throw
(
new
ApplicationException(
"
File not specified
"
));
}
else
if
(sourceFilename.Contains(
"
/
"
))
{
//
treat as a full path
target
=
AdjustDir(sourceFilename);
}
else
{
//
treat as filename only, use current directory
target
=
CurrentDirectory
+
sourceFilename;
}
string
URI
=
Hostname
+
target;
//
3. perform copy
System.Net.FtpWebRequest ftp
=
GetRequest(URI);
//
Set request to download a file in binary mode
ftp.Method
=
System.Net.WebRequestMethods.Ftp.DownloadFile;
ftp.UseBinary
=
true
;
//
open request and get response stream
using
(FtpWebResponse response
=
(FtpWebResponse)ftp.GetResponse())
{
using
(Stream responseStream
=
response.GetResponseStream())
{
//
loop to read & write to file
using
(FileStream fs
=
targetFI.OpenWrite())
{
try
{
byte
[] buffer
=
new
byte
[
2048
];
int
read
=
0
;
do
{
read
=
responseStream.Read(buffer,
0
, buffer.Length);
fs.Write(buffer,
0
, read);
}
while
(
!
(read
==
0
));
responseStream.Close();
fs.Flush();
fs.Close();
}
catch
(Exception)
{
//
catch error and delete file only partially downloaded
fs.Close();
//
delete target file as it's incomplete
targetFI.Delete();
throw
;
}
}
responseStream.Close();
}
response.Close();
}
return
true
;
}
#endregion
#11楼 得分:0 回复于:2008-06-23 08:48:53
似乎是发送MAIL的
C# code
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Net.Mail;
using
System.Diagnostics;
namespace
MailTest
{
class
Program
{
static
void
Main(
string
[] args)
{
Encoding encoding
=
Encoding.GetEncoding(
"
GB2312
"
);
MailAddress
from
=
new
MailAddress(
"
youmailname@163.com
"
,
"
19850101
"
, encoding);
MailAddress to
=
new
MailAddress(
"
youmailname@163.com
"
);
MailMessage mail
=
new
MailMessage(
from
, to);
mail.Subject
=
"
test
"
;
mail.Body
=
"
hello world
"
;
mail.SubjectEncoding
=
encoding;
mail.BodyEncoding
=
encoding;
SmtpClient smtp
=
new
SmtpClient(
"
smtp.163.com
"
);
smtp.DeliveryMethod
=
SmtpDeliveryMethod.Network;
smtp.UseDefaultCredentials
=
true
;
smtp.Credentials
=
new
System.Net.NetworkCredential(
"
rjgcwwdz@163.com
"
,
"
19850101
"
);
smtp.Send(mail);
}
}
}
#12楼 得分:0 回复于:2008-06-23 08:50:21
类似QQ通讯:
C# code
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Net;
using
System.IO;
using
System.Net.Sockets;
using
System.Threading;
namespace
MyQQSer
{
class
Serv
{
private
TcpListener listenr;
private
Thread thread;
private
bool
isClose
=
false
;
//
结束程序是退出循环
private
Socket[] sock
=
new
Socket[
50
];
public
Serv()
{
Listener();
}
~
Serv()
{
isClose
=
true
;
for
(
int
i
=
0
; i
<
sock.Length; i
++
)
{
if
(sock[i]
!=
null
)
sock[i].Close();
listenr.Stop();
}
}
///
<summary>
///
开始监听端口
///
</summary>
public
void
Listener()
{
if
(listenr
==
null
)
listenr
=
new
TcpListener(IPAddress.Parse(
"
127.0.0.1
"
),
5000
);
listenr.Start();
if
(thread
==
null
)
thread
=
new
Thread(
new
ThreadStart(ReciverMessage));
thread.IsBackground
=
true
;
thread.Start();
}
///
<summary>
///
接收数据
///
</summary>
private
void
ReciverMessage()
{
int
count;
//
可用套结字索引
count
=
GetCount();
bool
loop
=
true
;
if
(count
==
-
1
)
loop
=
false
;
if
(loop)
{
while
(
true
)
{
//
判断是否退出循环
if
(isClose)
break
;
sock[count]
=
listenr.AcceptSocket();
Thread t
=
new
Thread(
new
ThreadStart(ReciverMessage));
t.IsBackground
=
true
;
t.Start();
//
接受客户端数据
while
(
true
)
{
byte
[] buffs
=
new
byte
[
100
];
if
(sock[count].Connected)
{
try
{
sock[count].Receive(buffs);
string
message
=
Encoding.Default.GetString(buffs);
Console.WriteLine(message);
SendToAll(buffs);
}
catch
(Exception ex)
{
}
}
}
}
}
Thread.CurrentThread.Abort();
}
//
得到可用套结字索引
private
int
GetCount()
{
for
(
int
i
=
0
; i
<
sock.Length; i
++
)
if
(sock[i]
==
null
)
return
i;
return
-
1
;
}
//
发送消息给所有人
private
void
SendToAll(
byte
[] buff)
{
for
(
int
i
=
0
; i
<
sock.Length; i
++
)
{
if
(sock[i]
!=
null
)
{
if
(sock[i].Connected)
{
sock[i].Send(buff);
}
}
}
}
}
}
C# code
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Text;
using
System.Windows.Forms;
using
System.Net.Sockets;
using
System.Net;
using
System.Threading;
using
System.IO;
namespace
TestClient
{
public
partial
class
Form1 : Form
{
private
TcpClient client;
private
Thread t;
private
Socket sock;
private
bool
close
=
false
;
public
Form1()
{
InitializeComponent();
}
//
连接
private
void
btnConnect_Click(
object
sender, EventArgs e)
{
if
(client
==
null
)
client
=
new
TcpClient(
new
IPEndPoint(IPAddress.Parse(
"
127.0.0.1
"
),
int
.Parse(txtLoalPort.Text)));
if
(t
==
null
)
t
=
new
Thread(
new
ThreadStart(ReciverMessage));
t.IsBackground
=
true
;
t.Start();
btnSend.Enabled
=
true
;
btnConnect.Enabled
=
false
;
}
//
接收消息
private
void
ReciverMessage()
{
client.Connect(IPAddress.Parse(txtSerIP.Text),
int
.Parse(txtSerPort.Text));
while
(
true
)
{
if
(close)
break
;
//
NetworkStream nws = client.GetStream();
//
StreamReader sr = new StreamReader(nws);
//
string message = sr.ReadToEnd();
//
sr.Close();
if
(sock
==
null
)
sock
=
client.Client;
byte
[] buff
=
new
byte
[
100
];
sock.Receive(buff);
string
message
=
Encoding.Default.GetString(buff);
this
.lstMessage.Items.Add(message);
}
Thread.CurrentThread.Abort();
}
//
发送消息
private
void
btnSend_Click(
object
sender, EventArgs e)
{
string
message
=
this
.txtInput.Text;
byte
[] buff
=
Encoding.Default.GetBytes(message);
sock.Send(buff);
txtInput.Text
=
""
;
}
private
void
Form1_FormClosing(
object
sender, FormClosingEventArgs e)
{
close
=
true
;
sock.Close();
}
}
}
#13楼 得分:0 回复于:2008-06-23 08:53:32
还有个remoting的:
C# code
using
System;
namespace
Remotable
{
public
class
RemotableType : MarshalByRefObject
{
private
string
_internalString
=
"
This is the RemotableType.
"
;
public
string
StringMethod()
{
return
_internalString;
}
}
}
using
System;
using
System.Runtime.Remoting;
namespace
RemotingFirst
{
public
class
Listener
{
public
static
void
Main()
{
RemotingConfiguration.Configure(
"
Listener.exe.config
"
);
Console.WriteLine(
"
Listening for requests. Press Enter to exit
"
);
Console.ReadLine();
}
}
}
using
System;
using
System.Runtime.Remoting;
namespace
Client
{
public
class
Client
{
public
static
void
Main()
{
RemotingConfiguration.Configure(
"
Client.exe.config
"
);
Remotable.RemotableType remoteObject
=
new
Remotable.RemotableType();
Console.WriteLine(remoteObject.StringMethod());
}
}
}
Listener.exe.config
<?
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
configuration
>
<
system.runtime.remoting
>
<
application
>
<
service
>
<
wellknown
mode
=
"
Singleton
"
type
=
"
Remotable.RemotableType, RemotableType
"
objectUri
=
"
RemotableType.rem
"
/>
</
service
>
<
channels
>
<
channel
ref
=
"
http
"
port
=
"
8989
"
/>
</
channels
>
</
application
>
</
system.runtime.remoting
>
</
configuration
>
#14楼 得分:0 回复于:2008-06-23 08:54:20
一个通讯类,类似教程的:
实只要用到Socket联接,基本上就得使用Thread,是交叉使用的。
C#封装的Socket用法基本上不算很复杂,只是不知道托管之后的Socket有没有其他性能或者安全上的问题。
在C#里面能找到的最底层的操作也就是socket了,概念不做解释。
程序模型如下:
WinForm程序 : 启动端口侦听;监视Socket联接情况;定期关闭不活动的联接;
Listener:处理Socket的Accept函数,侦听新链接,建立新Thread来处理这些联接(Connection)。
Connection:处理具体的每一个联接的会话。
1:WinForm如何启动一个新的线程来启动Listener:
//start the server
private void btn_startServer_Click(object sender, EventArgs e)
{
//this.btn_startServer.Enabled = false;
Thread _createServer = new Thread(new ThreadStart(WaitForConnect));
_createServer.Start();
}
//wait all connections
private void WaitForConnect()
{
SocketListener listener = new SocketListener(Convert.ToInt32(this.txt_port.Text));
listener.StartListening();
}
因为侦听联接是一个循环等待的函数,所以不可能在WinForm的线程里面直接执行,不然Winform也就是无法继续任何操作了,所以才指定一个新的线程来执行这个函数,启动侦听循环。
这一个新的线程是比较简单的,基本上没有启动的参数,直接指定处理函数就可以了。
2:Listener如何启动循环侦听,并且启动新的带有参数的线程来处理Socket联接会话。
先看如何建立侦听:(StartListening函数)
IPEndPoint localEndPoint = new IPEndPoint(_ipAddress, _port);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(20);//20 trucks
// Start listening for connections.
while (true)
{
// here will be suspended while waiting for a new connection.
Socket connection = listener.Accept();
Logger.Log("Connect", connection.RemoteEndPoint.ToString());//log it, new connection
……
}
}……
基本步骤比较简单:
建立本机的IPEndPoint对象,表示以本机为服务器,在指定端口侦听;
然后绑定到一个侦听Socket上;
进入while循环,等待新的联接;
如果有新的联接,那么建立新的socket来对应这个联接的会话。
值得注意的就是这一句联接代码:listener.Accept()。执行这一句的时候,程序就在这个地方等待,直到有新的联检请求的时候程序才会执行下一句。这是同步执行,当然也可以异步执行。
新的联接Socket建立了(Accept之后),对于这些新的socket该怎么办呢?他们依然是一个循环等待,所以依然需要建立新的Thread给这些Socket去处理会话(接收/发送消息),而这个Thread就要接收参数了。
Thread本身是不能接收参数的,为了让它可以接收参数,可以采用定义新类,添加参数作为属性的方法来解决。
因为每一个Socket是一个Connection周期,所以我定义了这么一个类public class Connection。这个类至少有这样一个构造函数public Connection(Socket socket); 之所以这么做,就是为了把Socket参数传给这个Connection对象,然后好让Listener启动这个Thread的时候,Thread可以知道他正在处理哪一个Socket。
具体处理的方法:(在Listener的StartListening函数,ocket connection = listener.Accept();之后)
Connection gpsCn = new Connection(connection);
//each socket will be wait for data. keep the connection.
Thread thread = new Thread(new ThreadStart(gpsCn.WaitForSendData));
thread.Name = connection.RemoteEndPoint.ToString();
thread.Start();
如此一来,这个新的socket在Accept之后就在新的Thread中运行了。
3:Connection的会话处理
建立了新的Connection(也就是socket),远程就可以和这个socket进行会话了,无非就是send和receive。
现在先看看怎么写的这个线程运行的Connection. WaitForSendData函数
while (true)
{
bytes = new byte[1024];
string data = "";
//systm will be waiting the msg of receive envet. like Accept();
//here will be suspended while waiting for socket income msg.
int bytesRec = this._connection.Receive(bytes);
_lastConnectTime = DateTime.Now;
if (bytesRec == 0)//close envent
{
Logger.Log("Close Connection", _connection.RemoteEndPoint.ToString());
break;
}
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
//…….handle your data.
}
可以看到这个处理的基本步骤如下:
执行Receive函数,接收远程socket发送的信息;
把信息从字节转换到string;
处理该信息,然后进入下一个循环,继续等待socket发送新的信息。
值得注意的有几个:
1:Receive函数。这个函数和Listener的Accept函数类似。在这个地方等待执行,如果没有新的消息,这个函数就不会执行下一句,一直等待。
2:接收的是字节流,需要转化成字符串
3:判断远程关闭联接的方式
4:如果对方的消息非常大,还得循环接收这个data。
4:如何管理这些联接(thread)
通过上边的程序,基本上可以建立一个侦听,并且处理联接会话。但是如何管理这些thread呢?不然大量产生thread可是一个灾难。
管理的方法比较简单,在Listener里面我定义了一个静态的哈希表(static public Hashtable Connections=new Hashtable();),存储Connection实例和它对应的Thread实例。而connection中也加入了一个最后联接时间的定义(private DateTime _lastConnectTime;)。在新链接建立的时候(Listener的Accept()之后)就把Connection实例和Thread实例存到哈希表中;在Connection的Receive的时候修改最后联接时间。这样我们就可以知道该Connection在哪里,并且会话是否活跃。
然后在Winform程序里头可以管理这些会话了,设置设置超时。
#15楼 得分:0 回复于:2008-06-23 08:54:48
在网络环境下,我们最感兴趣的两个命名空间是System.Net和 System.Net.Sockets。System.Net命名空间通常与较高程的操作有关,例如download或upload,试用HTTP和其他协议进行Web请求等等,而System.Net.Sockets命名空间所包含的类通常与较低程的操作有关。如果要直接使用Sockets或者 TCP/IP之类的协议,这个命名空间的类是非常有用的。
在.Net中,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现。System.Net 命名空间中的所有其他网络访问类都建立在该套接字Socket实现之上,如TCPClient、TCPListener 和 UDPClient 类封装有关创建到 Internet 的 TCP 和 UDP 连接的详细信息;NetworkStream类则提供用于网络访问的基础数据流等,常见的许多Internet服务都可以见到Socket的踪影,如 Telnet、Http、Email、Echo等,这些服务尽管通讯协议Protocol的定义不同,但是其基础的传输都是采用的Socket。
其实,Socket可以象流Stream一样被视为一个数据通道,这个通道架设在应用程序端(客户端)和远程服务器端之间,而后,数据的读取(接收)和写入(发送)均针对这个通道来进行。
可见,在应用程序端或者服务器端创建了Socket对象之后,就可以使用Send/SentTo方法将数据发送到连接的Socket,或者使用Receive/ReceiveFrom方法接收来自连接Socket的数据。
针对Socket编程,.NET 框架的 Socket 类是 Winsock32 API 提供的套接字服务的托管代码版本。其中为实现网络编程提供了大量的方法,大多数情况下,Socket 类方法只是将数据封送到它们的本机 Win32 副本中并处理任何必要的安全检查。如果你熟悉Winsock API函数,那么用Socket类编写网络程序会非常容易,当然,如果你不曾接触过,也不会太困难,跟随下面的解说,你会发觉使用Socket类开发 windows 网络应用程序原来有规可寻,它们在大多数情况下遵循大致相同的步骤。
在使用之前,你需要首先创建Socket对象的实例,这可以通过Socket类的构造方法来实现:
public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolType);
其中,addressFamily 参数指定 Socket 使用的寻址方案,socketType 参数指定 Socket 的类型,protocolType 参数指定 Socket 使用的协议。
下面的示例语句创建一个 Socket,它可用于在基于 TCP/IP 的网络(如 Internet)上通讯。
Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
若要使用 UDP 而不是 TCP,需要更改协议类型,如下面的示例所示:
Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
一旦创建 Socket,在客户端,你将可以通过Connect方法连接到指定的服务器,并通过Send/SendTo方法向远程服务器发送数据,而后可以通过 Receive/ReceiveFrom从服务端接收数据;而在服务器端,你需要使用Bind方法绑定所指定的接口使Socket与一个本地终结点相联,并通过Listen方法侦听该接口上的请求,当侦听到用户端的连接时,调用Accept完成连接的操作,创建新的Socket以处理传入的连接请求。使用完 Socket 后,记住使用 Shutdown 方法禁用 Socket,并使用 Close 方法关闭 Socket。
可以看出,以上许多方法包含EndPoint类型的参数,在Internet中,TCP/IP 使用一个网络地址和一个服务端口号来唯一标识设备。网络地址标识网络上的特定设备;端口号标识要连接到的该设备上的特定服务。网络地址和服务端口的组合称为终结点,在 .NET 框架中正是由 EndPoint 类表示这个终结点,它提供表示网络资源或服务的抽象,用以标志网络地址等信息。.Net同时也为每个受支持的地址族定义了 EndPoint 的子代;对于 IP 地址族,该类为 IPEndPoint。IPEndPoint 类包含应用程序连接到主机上的服务所需的主机和端口信息,通过组合服务的主机IP地址和端口号,IPEndPoint 类形成到服务的连接点。
用到IPEndPoint类的时候就不可避免地涉及到计算机IP地址,System.Net命名空间中有两种类可以得到IP地址实例:
IPAddress类:IPAddress 类包含计算机在 IP 网络上的地址。其Parse方法可将 IP 地址字符串转换为 IPAddress 实例。下面的语句创建一个 IPAddress 实例:
IPAddress myIP = IPAddress.Parse("192.168.0.1");
Dns 类:向使用 TCP/IP Internet 服务的应用程序提供域名服务。其Resolve 方法查询 DNS 服务器以将用户友好的域名(如"host.mydomain.com")映射到数字形式的 Internet 地址(如 192.168.0.1)。Resolve方法 返回一个 IPHostEnty 实例,该实例包含所请求名称的地址和别名的列表。大多数情况下,可以使用 AddressList 数组中返回的第一个地址。下面的代码获取一个 IPAddress 实例,该实例包含服务器 host.mydomain.com 的 IP 地址。
IPHostEntry ipHostInfo = Dns.Resolve("host.mydomain.com ");
IPAddress ipAddress = ipHostInfo.AddressList[0];
你也可以使用GetHostName方法得到IPHostEntry实例:
IPHosntEntry hostInfo=Dns.GetHostByName("host.mydomain.com ")
在使用以上方法时,你将可能需要处理以下几种异常:
SocketException异常:访问Socket时操作系统发生错误引发
ArgumentNullException异常:参数为空引用引发
ObjectDisposedException异常:Socket已经关闭引发
在掌握上面得知识后,下面的代码将该服务器主机( host.mydomain.com的 IP 地址与端口号组合,以便为连接创建远程终结点:
IPEndPoint ipe = new IPEndPoint(ipAddress,11000);
确定了远程设备的地址并选择了用于连接的端口后,应用程序可以尝试建立与远程设备的连接。下面的示例使用现有的 IPEndPoint 实例与远程设备连接,并捕获可能引发的异常:
try
{
temp.Connect(ipe);//尝试连接
}
//处理参数为空引用异常
catch(ArgumentNullException ae)
{
Console.WriteLine("ArgumentNullException : {0}", ae.ToString());
}
//处理操作系统异常
catch(SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
需要知道的是:Socket 类支持两种基本模式:同步和异步。其区别在于:在同步模式中,对执行网络操作的函数(如 Send 和 Receive)的调用一直等到操作完成后才将控制返回给调用程序。在异步模式中,这些调用立即返回。
综合运用以上阐述的使用Visual C#进行Socket网络程序开发的知识,下面的程序是一个简单的Socket通讯实例,client向server发送一段测试字符串,server接收并显示出来,给予client成功相应。
//client端
using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace socketsample
{
class Class1
{
static void Main()
{
try
{
int port = 2000;
string host = "127.0.0.1";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
c.Connect(ipe);
string sendStr = "hello!This is a socket test";
byte[] bs = Encoding.ASCII.GetBytes(sendStr);
c.Send(bs, bs.Length, 0);
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
bytes = c.Receive(recvBytes, recvBytes.Length, 0);
recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
Console.WriteLine(recvStr);
c.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.ReadLine();
}
}
}
//server端
using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace Project1
{
class Class2
{
static void Main()
{
try
{
int port = 2000;
string host = "127.0.0.1";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Bind(ipe);
s.Listen(0);
Socket temp = s.Accept();
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
bytes = temp.Receive(recvBytes, recvBytes.Length, 0);
recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
Console.WriteLine(recvStr);
string sendStr = "Ok!Sucess!";
byte[] bs = Encoding.ASCII.GetBytes(sendStr);
temp.Send(bs, bs.Length, 0);
temp.Shutdown(SocketShutdown.Both);
temp.Close();
s.Shutdown(SocketShutdown.Both);
s.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.ReadLine();
}
}
}
以上程序在VS Express 2005 .Net2.0环境下测试通过。
#16楼 得分:1 回复于:2008-06-23 08:55:31
#17楼 得分:0 回复于:2008-06-23 08:57:37
koobee学生在校写的《银证转帐系统》的通信代码
C# code
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Net;
using
System.Net.Sockets;
using
System.Threading;
using
System.Windows.Forms;
using
System.IO;
using
System.Data.SqlClient;
namespace
SERVERsocket
{
class
SERVER
{
private
Thread serverThread;
private
Thread recvThread;
private
TcpListener tcpListener;
private
NetworkStream networkStream;
private
StreamReader streamReader;
private
StreamWriter streamWriter;
private
Socket socketForClient;
private
string
message;
private
int
operatorNO;
private
bool
[] isOperated;
private
void
Listen()
{
try
{
Int32 port
=
Int32.Parse(
"
2020
"
);
IPAddress ipAddress
=
Dns.Resolve(
"
localhost
"
).AddressList[
0
];
tcpListener
=
new
TcpListener(IPAddress.Any, port);
//
开始侦听
tcpListener.Start();
//
返回可以用以处理连接的Socket实例
socketForClient
=
tcpListener.AcceptSocket();
if
(socketForClient.Connected)
{
networkStream
=
new
NetworkStream(socketForClient);
streamReader
=
new
StreamReader(networkStream);
streamWriter
=
new
StreamWriter(networkStream);
recvThread
=
new
Thread(
new
ThreadStart(RecvData));
recvThread.Start();
}
MessageBox.Show(
"
客户端成功连接上服务器!
"
);
}
catch
(Exception exc)
{
MessageBox.Show(exc.Message,
"
Server提示
"
);
}
}
//
接收数据
private
void
RecvData()
{
string
msg
=
streamReader.ReadLine();
string
[] tokens
=
msg.Split(
new
char
[] {
'
#
'
});
//
MessageBox.Show(tokens[0]);
//
MessageBox.Show(tokens[1]);
//
MessageBox.Show(tokens[2]);
while
(
!
msg.Equals(
"
clientExit
"
))
{
switch
(tokens[
0
])
{
case
"
c01
"
:
{
//
MessageBox.Show("开始登陆!");
//
下面写SQL语句,查询对应的帐户密码是否正确,并返回信息
SqlConnection thisConnection
=
new
SqlConnection(
"
server = localhost;Integrated Security =true;database = security
"
);
SqlCommand comn
=
new
SqlCommand(
"
select 密码 from 帐户表 where 账号=
"
+
tokens[
1
], thisConnection);
thisConnection.Open();
SqlDataAdapter thisAdapt
=
new
SqlDataAdapter(
"
select * from 帐户表
"
, thisConnection);
DataSet thisDataSet
=
new
DataSet();
thisAdapt.Fill(thisDataSet,
"
帐户表
"
);
string
s
=
comn.ExecuteScalar().ToString();
//
MessageBox.Show(s);
//
MessageBox.Show(tokens[2]);
if
(s.CompareTo(tokens[
2
])
==
0
)
{
streamWriter.Write(
"
1
"
);
streamWriter.Flush();
tokens[
0
].Remove(
0
);
//
MessageBox.Show("登陆消息已发送");
}
else
{
streamWriter.Write(
"
1
"
);
streamWriter.Flush();
tokens[
0
].Remove(
0
);
//
MessageBox.Show("登陆");
}
}
break
;
case
"
c02
"
:
{
//
下面写SQL语句,查询对应账户的余额,并返回信息
SqlConnection thisConnection
=
new
SqlConnection(
"
server = localhost;Integrated Security =true;database = security;
"
);
SqlDataAdapter thisAdapt
=
new
SqlDataAdapter(
"
select * from 帐户表
"
, thisConnection);
SqlCommandBuilder thisbuider
=
new
SqlCommandBuilder(thisAdapt);
SqlCommand thisCommand
=
thisConnection.CreateCommand();
thisConnection.Open();
DataSet thisDataSet
=
new
DataSet();
thisAdapt.Fill(thisDataSet,
"
帐户表
"
);
string
s1
=
"
select 金额 from 帐户表 where 账号=
"
+
tokens[
1
];
setMessage(
"
c002#
"
+
s1);
//
填写账户余额
SendData();
tokens[
0
].Remove(
0
);
}
break
;
case
"
c03
"
:
{
//
更改帐户密码的sql语句,完成后返回数据003成功
SqlConnection thisConnection
=
new
SqlConnection(
"
server = localhost;Integrated Security =true;database = security;
"
);
SqlDataAdapter thisAdapt
=
new
SqlDataAdapter(
"
select * from 帐户表
"
, thisConnection);
SqlCommandBuilder thisbuider
=
new
SqlCommandBuilder(thisAdapt);
SqlCommand thisCommand
=
thisConnection.CreateCommand();
thisConnection.Open();
DataSet thisDataSet
=
new
DataSet();
thisAdapt.Fill(thisDataSet,
"
帐户表
"
);
foreach
(DataRow rows
in
thisDataSet.Tables[
"
帐户表
"
].Rows)
{
string
s1
=
"
select 密码 from 帐户表 where 账号=
"
+
tokens[
1
];
if
(s1.CompareTo(tokens[
1
])
==
0
)
{
thisCommand.CommandText
=
"
update 帐户表 set 密码 =
"
+
tokens[
3
]
+
"
where 账号=
"
+
tokens[
1
];
setMessage(
"
c003#1
"
);
//
修改密码成功
SendData();
tokens[
0
].Remove(
0
);
}
else
{
setMessage(
"
c003#2
"
);
//
修改密码失败
SendData();
tokens[
0
].Remove(
0
);
}
}
}
break
;
#18楼 得分:0 回复于:2008-06-23 08:58:06
C# code
case
"
c04
"
:
{
operatorNO
=
Int32.Parse(tokens[
1
]);
if
(isOperated[operatorNO])
//
这句要查下,c#中的bool初始值是什么?true还是false
{
SendData();
isOperated[operatorNO]
=
true
;
//
将“已操作”标记设置为true
}
else
{
//
执行转账操作的SQL语句,完成后并返回信息
SqlConnection thisConnection
=
new
SqlConnection(
"
server = localhost;Integrated Security =true;database = security;
"
);
SqlDataAdapter thisAdapt
=
new
SqlDataAdapter(
"
select * from 帐户表
"
, thisConnection);
thisConnection.Open();
SqlCommand thisCommand
=
thisConnection.CreateCommand();
DataSet thisDataSet
=
new
DataSet();
thisAdapt.Fill(thisDataSet,
"
帐户表
"
);
string
s2
=
"
select 金额 from 帐户表 where 账号=
"
+
tokens[
1
];
string
s3
=
"
select 金额 from 帐户表 where 账号=
"
+
tokens[
1
];
if
(s2.CompareTo(tokens[
3
])
<
0
)
setMessage(
"
c004#1
"
);
else
if
(s3
==
null
)
setMessage(
"
c004#2
"
);
else
{
foreach
(DataRow rows
in
thisDataSet.Tables[
"
帐户表
"
].Rows)
{
if
(rows[
"
账号
"
].ToString()
==
tokens[
1
])
thisCommand.CommandText
=
"
update 帐户表 set 金额 = 金额 -
"
+
tokens[
3
]
+
"
where 账号=
"
+
tokens[
1
];
if
(rows[
"
账号
"
].ToString()
==
tokens[
2
])
thisCommand.CommandText
=
"
update 帐户表 set 金额 = 金额 +
"
+
tokens[
3
]
+
"
where 账号=
"
+
tokens[
2
];
}
setMessage(
"
c004#3
"
);
}
SendData();
tokens[
0
].Remove(
0
);
isOperated[operatorNO]
=
true
;
//
将“已操作”标记设置为true
}
}
break
;
case
"
c05
"
:
{
operatorNO
=
Int32.Parse(tokens[
1
]);
if
(isOperated[operatorNO])
//
这句要查下,c#中的bool初始值是什么?true还是false
{
SendData();
isOperated[operatorNO]
=
true
;
//
将“已操作”标记设置为true
}
else
{
//
执行转账操作的SQL语句,完成后并返回信息
}
SendData();
tokens[
0
].Remove(
0
);
isOperated[operatorNO]
=
true
;
//
将“已操作”标记设置为true
}
break
;
}
msg
=
streamReader.ReadLine();
}
MessageBox.Show(
"
一名客户退出
"
);
ReleaseResource();
startServer();
}
public
void
setMessage(
string
message)
{
this
.message
=
message;
}
private
void
SendData()
{
streamWriter.Write(message);
streamWriter.Flush();
//
streamWriter.Close();
}
private
void
ReleaseResource()
{
if
(networkStream
!=
null
)
{
networkStream.Close();
streamReader.Close();
streamWriter.Close();
socketForClient.Shutdown(SocketShutdown.Both);
socketForClient.Close();
tcpListener.Stop();
}
}
public
void
startServer()
{
serverThread
=
new
Thread(
new
ThreadStart(Listen));
serverThread.Start();
}
public
void
serverExit()
{
string
exitMsg
=
"
serverExit
"
;
//
要退出时,发送exit信息给服务器
setMessage(exitMsg);
SendData();
ReleaseResource();
}
}
#19楼 得分:0 回复于:2008-06-23 08:58:43
C# code
public
partial
class
BankClient
{
private
NetworkStream networkStream;
private
StreamReader streamReader;
private
StreamWriter streamWriter;
private
TcpClient myclient;
private
Thread recvThread;
private
Thread sendThread;
private
Thread serverThread;
private
bool
flag
=
true
;
private
void
Connection()
{
try
{
Int32 port
=
8888
;
myclient
=
new
TcpClient(
"
10.1.1.10
"
, port);
}
catch
{
MessageBox.Show(
"
没有连接到银行服务器!
"
);
}
networkStream
=
myclient.GetStream();
streamReader
=
new
StreamReader(networkStream);
streamWriter
=
new
StreamWriter(networkStream);
//
recvThread = new Thread(new ThreadStart(RecvData));
//
recvThread.Start();
MessageBox.Show(
"
连接到银行服务器!
"
);
}
private
void
RecvData()
{
string
s
=
streamReader.ReadLine();
string
[] tokens
=
s.Split(
new
char
[] {
'
#
'
});
while
(
!
s.Equals(
"
severExit
"
))
{
if
(tokens[
0
]
==
"
1
"
)
{
SqlConnection thisConnection
=
new
SqlConnection(
"
server = localhost;Integrated Security = true;database = security;
"
);
SqlDataAdapter thisAdapt
=
new
SqlDataAdapter(
"
select * from 转账接口表
"
, thisConnection);
SqlCommandBuilder thisbuider
=
new
SqlCommandBuilder(thisAdapt);
SqlCommand thisCommand
=
thisConnection.CreateCommand();
DataSet thisSet
=
new
DataSet();
thisAdapt.Fill(thisSet,
"
转账接口表
"
);
thisConnection.Open();
//
thisCommand.CommandText = "update 转账接口表 set 标志位 = 3" + "where 转账序号=" + tokens[1];
thisCommand.CommandText
=
"
delete from 转账接口表 where 转账序号=
"
+
tokens[
1
];
thisCommand.ExecuteNonQuery();
flag
=
true
;
}
else
flag
=
false
;
s
=
streamReader.ReadLine();
}
ReleaseResouce();
}
private
void
SendData()
{
SqlConnection thisConnection
=
new
SqlConnection(
"
server = localhost;Integrated Security = true;database = security;
"
);
SqlDataAdapter thisAdapt
=
new
SqlDataAdapter(
"
select * from 转账接口表
"
, thisConnection);
SqlCommandBuilder thisbuider
=
new
SqlCommandBuilder(thisAdapt);
SqlCommand thisCommand
=
thisConnection.CreateCommand();
DataSet thisSet
=
new
DataSet();
thisAdapt.Fill(thisSet,
"
转账接口表
"
);
thisConnection.Open();
foreach
(DataRow rows
in
thisSet.Tables[
"
转账接口表
"
].Rows)
{
if
(rows[
"
标志位
"
].ToString()
==
"
1
"
)
{
string
s;
s
=
rows[
"
转账序号
"
].ToString()
+
'
#
'
+
rows[
"
发起端账号
"
].ToString()
+
'
#
'
+
rows[
"
接收端账号
"
].ToString()
+
'
#
'
+
rows[
"
发生金额
"
]
+
'
#
'
+
rows[
"
标志位
"
].ToString();
if
(flag)
{
streamWriter
=
new
StreamWriter(networkStream);
streamWriter.WriteLine(s);
streamWriter.Flush();
System.Threading.Thread.Sleep(
5000
);
}
else
{
//
将数据读入资金变更表
thisCommand.CommandText
=
"
delete from 转账接口表 where 标志位= '3'
"
;
}
}
}
}
private
void
ReleaseResouce()
{
networkStream.Close();
streamReader.Close();
streamWriter.Close();
sendThread.Abort();
//
serverThread.Abort();
myclient.Close();
}
public
void
startBankClient( )
{
serverThread
=
new
Thread(
new
ThreadStart(Connection));
serverThread.Start();
int
row
=
0
;
SqlConnection thisConnection
=
new
SqlConnection(
"
server = localhost;Integrated Security = true;database = security;
"
);
SqlDataAdapter thisAdapt
=
new
SqlDataAdapter(
"
select * from 转账接口表
"
, thisConnection);
SqlCommandBuilder thisbuider
=
new
SqlCommandBuilder(thisAdapt);
DataSet thisSet
=
new
DataSet();
thisAdapt.Fill(thisSet,
"
转账接口表
"
);
while
(
true
)
{
foreach
(DataRow rows
in
thisSet.Tables[
"
转账接口表
"
].Rows)
{
row
++
;
}
if
(row
>
0
)
{
SendData();
RecvData();
}
System.Threading.Thread.Sleep(
5000
);
}
}
public
void
exitBankClient( )
{
streamWriter.Flush();
ReleaseResouce();
}
}
}
(福建师范大学软件学院)
http://topic.csdn.net/u/20080623/08/4bbd2475-45f1-42e3-a613-16b094759ade.html