C#网络编程(同步传输字符串) - Part.2
2009-03-26 08:20:05 来源:WEB开发网这里还需要注意一点,当客户端在TcpClient实例上调用Close()方法,或者在流上调用Dispose()方法,服务端的streamToClient.Read()方法会持续地返回0,但是不抛出异常,所以会产生一个无限循环;而如果直接关闭掉客户端,或者客户端执行完毕但没有调用stream.Dispose()或者TcpClient.Close(),如果服务器端此时仍阻塞在Read()方法处,则会在服务器端抛出异常:“远程主机强制关闭了一个现有连接”。因此,我们将服务端的streamToClient.Read()方法需要写在一个try/catch中。同理,如果在服务端已经连接到客户端之后,服务端调用remoteClient.Close(),则客户端会得到异常“无法将数据写入传输连接: 您的主机中的软件放弃了一个已建立的连接。”;而如果服务端直接关闭程序的话,则客户端会得到异常“无法将数据写入传输连接: 远程主机强迫关闭了一个现有的连接。”。因此,它们的读写操作必须都放入到try/catch块中。
2.服务端回发,客户端接收并输出
2.2服务端程序
我们接着再进行进一步处理,服务端将收到的字符串改为大写,然后回发,客户端接收后打印。此时它们的角色和上面完全进行了一下对调:对于服务端来说,就好像刚才的客户端一样,将字符串写入到流中;而客户端则同服务端一样,接收并打印。除此以外,我们最好对流的读写操作加上lock,现在我们直接看代码,首先看服务端:
class Server {
static void Main(string[] args) {
const int BufferSize = 8192; // 缓存大小,8192Bytes
ConsoleKey key;
Console.WriteLine("Server is running ... ");
IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
TcpListener listener = new TcpListener(ip, 8500);
listener.Start(); // 开始侦听
Console.WriteLine("Start Listening ...");
// 获取一个连接,同步方法,在此处中断
TcpClient remoteClient = listener.AcceptTcpClient();
// 打印连接到的客户端信息
Console.WriteLine("Client Connected!{0} <-- {1}",
remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);
// 获得流
NetworkStream streamToClient = remoteClient.GetStream();
do {
// 写入buffer中
byte[] buffer = new byte[BufferSize];
int bytesRead;
try {
lock(streamToClient){
bytesRead = streamToClient.Read(buffer, 0, BufferSize);
}
if (bytesRead == 0) throw new Exception("读取到0字节");
Console.WriteLine("Reading data, {0} bytes ...", bytesRead);
// 获得请求的字符串
string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received: {0}", msg);
// 转换成大写并发送
msg = msg.ToUpper();
buffer = Encoding.Unicode.GetBytes(msg);
lock(streamToClient){
streamToClient.Write(buffer, 0, buffer.Length);
}
Console.WriteLine("Sent: {0}", msg);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
break;
}
} while (true);
streamToClient.Dispose();
remoteClient.Close();
Console.WriteLine("nn输入"Q"键退出。");
do {
key = Console.ReadKey(true).Key;
} while (key != ConsoleKey.Q);
}
}
更多精彩
赞助商链接