.net网络编程之一:Socket编程
2009-03-18 10:28
381 查看
SocketThread类代码如下:
客户端请求的Socket代码如下(与前面两个类位于不同的控制台项目中):
上面的三个类位于两个控制台项目中ServerSocket类和SocketThread类位于同一个类库项目中,其中ClientSocket类位于另一个控制台项目中,编译之后会生成两个exe文件,运行的时候首先运行服务器端exe程序以便监听,再运行客户端exe程序。这个程序运行的效果如下:
注意,在终止程序的时候首先在客户端向服务器发送一个自定义的字符串“<EOF>”,在客户端使用命令行参数“bye”就是发送这个字符串的,这样就会正确终止服务器端响应Socket及正确关闭客户端请求的Socket,否则有可能抛出异常。
以上仅仅是演示了如何使用Socket进行编程,如果要传输文件的话,可能需要更多类似于关闭Socket的自定义字符串用以控制了。另外使用Socket来传输数据是比较高效的,但是传输控制相对来说要麻烦一点,针对网络中一些特殊场合的数据传输,可以使用特定的传输协议,在这个系列的后续文章中会继续介绍网络编程的有关知识。程序代码稍后整理之后提供下载。
using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Net.Sockets; namespace ServerSocket { /// <summary> /// 用于处理客户端请求的Socket /// 作者:周公 /// 编写时间:2009-03-18 /// </summary> public class SocketThread:IDisposable { private Socket socket; private Thread thread; private bool isListening = false; private string text; /// <summary> /// 构造方法 /// </summary> /// <param name="socket">用于处理客户端应答的Socket</param> public SocketThread(Socket socket) { this.socket = socket; isListening = true; thread = new Thread(new ThreadStart(Work)); thread.Start(); } public void Work() { byte[] buffer=new byte[1024]; while (isListening) { int receivedLength = socket.Receive(buffer); text=System.Text.Encoding.UTF8.GetString(buffer,0,receivedLength); //<EOF>是自定义的协议,表示中止消息交流 if (text.IndexOf("<EOF>") > -1) { isListening=false; socket.Send(new byte[] { 0 }); } else { //Console.WriteLine("接收到的数据:" + text); //根据客户端的请求获取相应的响应信息 string message = GetMessage(text); //将响应信息以字节的方式发送到客户端 socket.Send(Encoding.UTF8.GetBytes(message)); } } } private string GetMessage(string request) { string message = string.Empty; //Console.WriteLine("Message=" + request); switch (request) { case "date": message = "服务器日期:"+DateTime.Now.ToString("yyyy-MM-dd"); break; case "time": message ="服务器时间:"+ DateTime.Now.ToString("HH:mm:ss"); break; case "datetime": message = "服务器日期时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); break; case "year": message = "服务器年份:" + DateTime.Now.Year.ToString(); break; case "month": message = "服务器月份:" + DateTime.Now.Month.ToString(); break; case "day": message = "这是本月第" + DateTime.Now.Day.ToString()+"天"; break; default: message = "不正确的参数"; break; } return message; } #region IDisposable 成员 public void Dispose() { isListening = false; if (thread != null) { if (thread.ThreadState != ThreadState.Aborted) { thread.Abort(); } thread = null; } if (socket != null) { socket.Shutdown(SocketShutdown.Both); socket.Close(); } } #endregion } }
客户端请求的Socket代码如下(与前面两个类位于不同的控制台项目中):
using System; using System.Net; using System.Net.Sockets; using System.Text; namespace ServerSocket { /// <summary> /// 客户端请求的Socket包装类 /// 作者:周公 /// 编写时间:2009-03-18 /// </summary> public class ClientSocket:IDisposable { private Socket sender = null; private bool isListening = false; //定义用于接收服务器响应的存储区. private byte[] bytes = new byte[1024]; //用于终止Soket的消息 private string shutDownMessage = "<EOF>"; public ClientSocket() { try { //设置要连接的主机信息并使用11000作为监听端口. IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000); // 创建一个TCP/IP协议的socket连接 sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sender.Connect(remoteEP); isListening = true; } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } public void StartClient() { // 连接到远程主机,并捕获所有信息 try { Console.WriteLine("连接到主机{0}", sender.RemoteEndPoint.ToString()); OutParameters(); string consoleMessage = Console.ReadLine(); while (isListening&&!string.IsNullOrEmpty(consoleMessage)) { consoleMessage = consoleMessage.ToLower(); if (consoleMessage == "bye") { SendShutDownMessage(); } else { string resultMessage=SendMessage(consoleMessage); Console.WriteLine(resultMessage); OutParameters(); consoleMessage = Console.ReadLine(); //Console.WriteLine("consoleMessage=" + consoleMessage); } } } catch (ArgumentNullException ane) { Console.WriteLine("参数异常 : {0}", ane.ToString()); } catch (SocketException se) { Console.WriteLine("出现Socket异常: {0}", se.ToString()); } catch (Exception e) { Console.WriteLine("出现了异常 : {0}", e.ToString()); } } /// <summary> /// 向远程主机发送信息 /// </summary> /// <param name="message">要发送的信息</param> public string SendMessage(string message) { byte[] buffer = Encoding.UTF8.GetBytes(message); sender.Send(buffer); int count=sender.Receive(bytes); return Encoding.UTF8.GetString(bytes, 0, count); } /// <summary> /// 向服务器发送关闭Socket信息,并中止与服务器的连接 /// </summary> public void SendShutDownMessage() { SendMessage(shutDownMessage); Console.WriteLine("已经关闭与服务器的连接"); isListening = false; Environment.Exit(0); } private void OutParameters() { Console.WriteLine("参数说明:"); Console.WriteLine("获取服务器日期:date"); Console.WriteLine("获取服务器时间:time"); Console.WriteLine("获取服务器日期时间:datetime"); Console.WriteLine("获取服务器年份:year"); Console.WriteLine("获取服务器月份:month"); Console.WriteLine("获取服务器天数:day"); Console.WriteLine("关闭连接:bye"); Console.WriteLine("请输入你要进行的操作:"); } public static int Main(String[] args) { ClientSocket client = new ClientSocket(); client.StartClient(); return 0; } #region IDisposable 成员 public void Dispose() { isListening = false; if (sender != null) { sender.Shutdown(SocketShutdown.Both); sender.Close(); } } #endregion } }
上面的三个类位于两个控制台项目中ServerSocket类和SocketThread类位于同一个类库项目中,其中ClientSocket类位于另一个控制台项目中,编译之后会生成两个exe文件,运行的时候首先运行服务器端exe程序以便监听,再运行客户端exe程序。这个程序运行的效果如下:
注意,在终止程序的时候首先在客户端向服务器发送一个自定义的字符串“<EOF>”,在客户端使用命令行参数“bye”就是发送这个字符串的,这样就会正确终止服务器端响应Socket及正确关闭客户端请求的Socket,否则有可能抛出异常。
以上仅仅是演示了如何使用Socket进行编程,如果要传输文件的话,可能需要更多类似于关闭Socket的自定义字符串用以控制了。另外使用Socket来传输数据是比较高效的,但是传输控制相对来说要麻烦一点,针对网络中一些特殊场合的数据传输,可以使用特定的传输协议,在这个系列的后续文章中会继续介绍网络编程的有关知识。程序代码稍后整理之后提供下载。
相关文章推荐
- .net网络编程(3)Socket基础
- .net网络编程之一:Socket编程
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务1
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计2[使用IE浏览本页]
- 黑马程序员---.NET高级之网络套接字(Socket)编程
- .net网络编程之一:Socket编程
- .net网络编程之一:Socket编程
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务2
- .net网络编程之一:Socket编程
- .NET(C#)基于Socket编程实现平行主机之间网络通讯有图片传输的Demo演示
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务1[使用IE浏览本页]
- .net网络编程之一:Socket编程
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务3[聊天室]
- .net网络编程之一:Socket编程
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务4[聊天室]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务2[使用IE浏览本页]
- .net网络编程之一:Socket编程
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计1
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务3[聊天室][使用IE浏览本页]
- .net网络编程之一:Socket编程【转】