服务端回发,客户端接收并输出


1. 服务端程序

我们接着再进行进一步处理,服务端将收到的字符串改为大写,然后回发,客户端接收后打印。此时它们的角色和上面完全进行了一下 对调:对于服务端来 说,就好像刚才的客户端一样,将字符串写入到流中;而客户端则同服务端一样,接收并打印。除此以外,我们 最好对流的读写操作加上 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("\n\n 输入\"Q\"键退出。"); 
 do { 
 key = Console.ReadKey(true).Key; 
 } while (key != ConsoleKey.Q); 
 } 
} 

接下来是客户端:

class Client { 
 static void Main(string[] args) { 
 Console.WriteLine("Client Running ..."); 
 TcpClient client; 
 ConsoleKey key; 
 const int BufferSize = 8192; 
 try { 
 client = new TcpClient(); 
 client.Connect("localhost", 8500); // 与服务器连接
 } catch (Exception ex) { 
 Console.WriteLine(ex.Message); 
 return; 
 } 
 // 打印连接到的服务端信息
 Console.WriteLine("Server Connected!{0} --> {1}", 
 client.Client.LocalEndPoint, client.Client.RemoteEndPoint); 
 
 NetworkStream streamToServer = client.GetStream(); 
 Console.WriteLine("Menu: S - Send, X - Exit"); 
 do { 
 key = Console.ReadKey(true).Key; 
 if (key == ConsoleKey.S) { 
 // 获取输入的字符串
 Console.Write("Input the message: "); 
 string msg = Console.ReadLine(); 
 byte[] buffer = Encoding.Unicode.GetBytes(msg); // 获得缓存
 try { 
 lock(streamToServer){ 
 streamToServer.Write(buffer, 0, buffer.Length); // 发往服务器
 } 
 Console.WriteLine("Sent: {0}", msg); 
 int bytesRead; 
 buffer = new byte[BufferSize]; 
 lock(streamToServer){ 
 bytesRead = streamToServer.Read(buffer, 0, BufferSize); 
 } 
 msg = Encoding.Unicode.GetString(buffer, 0, bytesRead); 
 Console.WriteLine("Received: {0}", msg); 
 } catch (Exception ex) { 
 Console.WriteLine(ex.Message); 
 break; 
 } 
 } 
 } while (key != ConsoleKey.X); 
 streamToServer.Dispose(); 
 client.Close(); 
 Console.WriteLine("\n\n 输入\"Q\"键退出。"); 
 do { 
 key = Console.ReadKey(true).Key; 
 } while (key != ConsoleKey.Q); 
 } 
}

最后我们运行程序,然后输入一串英文字符串,然后看一下输出:

// 客户端
Client is running ... 
Server Connected!127.0.0.1:12662 --> 127.0.0.1:8500 
Menu: S - Send, X - Exit 
Input the message: Hello, I'm jimmy zhang. 
Sent: Hello, I'm jimmy zhang. 
Received: HELLO, I'M JIMMY ZHANG. 
// 服务端
Server is running ... 
Start Listening ... 
Client Connected!127.0.0.1:8500 <-- 127.0.0.1:12662 
Reading data, 46 bytes ... 
Received: Hello, I'm jimmy zhang. 
Sent: HELLO, I'M JIMMY ZHANG. 

看到这里,我想你应该对使用 TcpClient 和 TcpListener 进行 C#网络编程有了一个初步的认识,可以说是刚刚入门了,后面的路还很 长。 本章的所有操作都是同步操作,像上面的代码也只是作为一个入门的范例,实际当中,一个服务端只能为一个客户端提供服务的情况是 不存在的,下面就让我们 来看看上面所说的第四种情况,如何进行异步的服务端编程。

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
张国生
评论列表

发表评论

评论内容
昵称:
关联文章