socket通信问题
2015-12-11 14:55
218 查看
TCP:面向连接的,所以在服务端绑定端口后,需要监听Listen()是否有客户端发送请求,有的话,Accept()建立一个新的socket对象,用于发送和接收信息,
就想先建造了一条高速路,再建造一辆货车拉货。
UDP:无连接的,所以在服务端绑定端口后,不需要监听Listen(),也不用建立一个新的socket对象用于接收发送信息,但是在发送和接收时,要讲本身的端口
做参数发送给对方,这样在交流时,对方才能确定自己。
UDP协议:
Client端:
Server端:
当将服务层写成window服务时,如果客户端关闭,服务端会报错,“远程主机关闭了一个现有的链接”,然后整个服务都停止了。
解决办法:为socket对象设置低级操作模式
另外,在window服务中,定时控件是不能用的,但是也不报错,不提醒,如果要定时循环,
解决办法:
TCP协议:
服务端:
TCP图:
UDP图:
就想先建造了一条高速路,再建造一辆货车拉货。
UDP:无连接的,所以在服务端绑定端口后,不需要监听Listen(),也不用建立一个新的socket对象用于接收发送信息,但是在发送和接收时,要讲本身的端口
做参数发送给对方,这样在交流时,对方才能确定自己。
UDP协议:
Client端:
static void Main(string[] args) { int port = 2001; string strHost = GetAddressIP();// "127.0.0.1"; // 建立IP对象 IPAddress ip = IPAddress.Parse(strHost); // 建立端口对象 IPEndPoint ipe = new IPEndPoint(ip, port); // 创建socket对象 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); Console.WriteLine("连接中。。。"); // 向服务器发送消息 string strMsgToServe = "嗨,来自客户端的问候。。。"; // 转成二进制发送到服务端 byte[] bytMsgToServe = Encoding.UTF8.GetBytes(strMsgToServe); socket.SendTo(bytMsgToServe, bytMsgToServe.Length, SocketFlags.None, ipe); Console.WriteLine("消息已发送。。。"); //IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); EndPoint Remote = new IPEndPoint(IPAddress.Any, 0);//(EndPoint)sender; bytMsgToServe = new byte[1024]; int recv = socket.ReceiveFrom(bytMsgToServe, ref Remote);//接受来自服务器的数据 Console.WriteLine("Message received from{0}:", Remote.ToString()); Console.WriteLine("收到的服务端消息:"+Encoding.UTF8.GetString(bytMsgToServe, 0, recv)); socket.Close(); Console.ReadLine(); } /// <summary> /// 获取本地IP地址信息 /// </summary> public static string GetAddressIP() { ///获取本地的IP地址 string AddressIP = string.Empty; foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList) { if (_IPAddress.AddressFamily.ToString() == "InterNetwork") { AddressIP = _IPAddress.ToString(); } } return AddressIP; }
Server端:
static void Main(string[] args) { int port = 2001; string strHost = GetAddressIP();// "127.0.0.1"; // 创建终结点 IPAddress ip = IPAddress.Parse(strHost); // 创建网络端口 IPEndPoint ipe = new IPEndPoint(ip, port); // 创建socke,开始监听--SocketType枚举 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // 绑定端口 socket.Bind(ipe); Console.WriteLine("等待客户端连接。。。"); //IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);//定义要发送的计算机的地址 EndPoint Remote = new IPEndPoint(IPAddress.Any, 0);//(EndPoint)(sender); // 收到的二进制byte byte[] bytRecv = new byte[1024]; int intBytes = socket.ReceiveFrom(bytRecv, ref Remote);//接受来自服务器的数据 //Console.WriteLine("Message received from{0}:", Remote.ToString()); Console.WriteLine("收到的信息:-"+Encoding.UTF8.GetString(bytRecv, 0, intBytes)); string welcome = "Welcome to my test server!"; bytRecv = Encoding.ASCII.GetBytes(welcome); socket.SendTo(bytRecv, bytRecv.Length, SocketFlags.None, Remote); Console.ReadLine(); } /// <summary> /// 获取本地IP地址信息 /// </summary> public static string GetAddressIP() { ///获取本地的IP地址 string AddressIP = string.Empty; foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList) { if (_IPAddress.AddressFamily.ToString() == "InterNetwork") { AddressIP = _IPAddress.ToString(); } } return AddressIP; }
当将服务层写成window服务时,如果客户端关闭,服务端会报错,“远程主机关闭了一个现有的链接”,然后整个服务都停止了。
解决办法:为socket对象设置低级操作模式
// 为 Socket 设置低级操作模式,不然当客户端关闭的时候,会报错 uint IOC_IN = 0x80000000; uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
另外,在window服务中,定时控件是不能用的,但是也不报错,不提醒,如果要定时循环,
解决办法:
System.Timers.Timer tmrSelectCOM = new System.Timers.Timer(2000); tmrSelectCOM.Elapsed += new System.Timers.ElapsedEventHandler(tmrSelectCOM_Tick); tmrSelectCOM.Enabled = true;
TCP协议:
服务端:
static void Main(string[] args) { // ip地址,端口 int port = 2000; string strIp = GetAddressIP(); // IP对象 IPAddress ip = IPAddress.Parse(strIp); IPEndPoint ipe = new IPEndPoint(ip, port); // 实例化socket对象 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 绑定端口 socket.Bind(ipe); // 监听 socket.Listen(0); // 为发送请求的客户端创建新的socket对象 Socket temp = socket.Accept(); // 接收消息 byte[] bytRecv = new byte[1024]; int intCount = temp.Receive(bytRecv,bytRecv.Length,0); string strRecv = Encoding.UTF8.GetString(bytRecv, 0, intCount); Console.WriteLine(strRecv); // 发送消息 string strSendMsg = "来自服务端的问候。。。"; byte[] bytSendMsg = Encoding.UTF8.GetBytes(strSendMsg); temp.Send(bytSendMsg, 0, bytSendMsg.Length, 0); Console.WriteLine("服务端消息已发送。。。"); Console.ReadLine(); } private static string GetAddressIP() { string strAddressIP = string.Empty; foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList) { if (address.AddressFamily.ToString() == "InterNetwork") { strAddressIP = address.ToString(); } } return strAddressIP; }客户端:
public static void Main(string[] args) { int port = 2000; string strIp = GetAddressIP(); // IP对象 IPAddress ip = IPAddress.Parse(strIp); IPEndPoint ipe = new IPEndPoint(ip, port); // 创建socket对象 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 连接 socket.Connect(ipe); Console.WriteLine("已连接。。。"); // 发送信息 string strSendMsg="来自客户端的问候。。。"; byte[] bytSendMsg = Encoding.UTF8.GetBytes(strSendMsg); socket.Send(bytSendMsg, 0, bytSendMsg.Length, SocketFlags.None); Console.WriteLine("消息已发送。。。"); // 接收 byte[] bytRecvMsg = new byte[1024]; int intCount = socket.Receive(bytRecvMsg); string strRecvMsg = Encoding.UTF8.GetString(bytRecvMsg, 0, intCount); Console.WriteLine(strRecvMsg); Console.ReadLine(); } private static string GetAddressIP() { // 获取本地的IP地址 string AddressIP = string.Empty; foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList) { if (_IPAddress.AddressFamily.ToString() == "InterNetwork") { AddressIP = _IPAddress.ToString(); } } return AddressIP; }
TCP图:
UDP图:
相关文章推荐
- Android中 ScrollView(ListView)中嵌套ListView时显示不全的简便解决方案
- PHP之curl put方式提交与接受数据
- IOS各种调试
- putty如何退出全屏模式
- jQuery使用$.ajax提交表单完整实例
- Go语言变量类型
- 计算机组成原理----第一章计算机系统概论---错题集第一部分
- iOS中NSThread多线程如何使用?
- 两种Java数字交换算法哪个快。
- 中断处理的tasklet(小任务)机制-不过如此
- 利用Mxnet自带的工具,进行数据转化,读取图片文件
- Java的读文件和写文件
- java android maven环境变量基本配置
- ViewPager的adapter
- 【MVC5】画面多按钮提交
- Javascript变长参数和默认参数
- 百度地图使用2-自定义覆盖物
- console.log()
- 创建Node Js应用
- Comparable和Comparator以及Arrays.sort方法