zoukankan      html  css  js  c++  java
  • [C#参考]利用Socket连续发送数据


    这个例子只是一个简单的连续发送数据,接收数据的DEMO。因为最近做一个项目,要求robot连续的通过Socket传回自己的当前的位置坐标,然后客户端接收到坐标信息,在本地绘制地图,实时显示robot的位置。

    里面还有好多的问题,在实际的项目中一定要解决,不然肯定跑步起来。比如:消息边界问题(帧的边界)、消息命令的解析等


    下面直接代码:

    服务器的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
     
    namespace ConsoleApplication6
    {
        class Program
        {
            //定义接收缓冲数组,端口号,监听socket
            private static byte[] buffer = new byte[1024];
            private static int port = 8887;
            private static Socket serverSocket;
     
            static void Main(string[] args)
            {
                //服务器IP地址
                IPAddress ip = IPAddress.Parse("127.0.0.1");
     
                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                serverSocket.Bind(new IPEndPoint(ip, port));//绑定IP地址:端口
                serverSocket.Listen(10);//设定最多10个连接请求排队
                Console.WriteLine("监听:" + serverSocket.LocalEndPoint.ToString());
     
                //建立线程监听client连接请求
                Thread myThread = new Thread(ListenClientConnection);
                //myThread.IsBackground = true;
                myThread.Start();
     
            }//Main()
     
            /// <summary>
            /// 新线程:监听客户端连接
            /// </summary>
            private static void ListenClientConnection()
            {
                while (true)
                {
                    Socket clientSocket = serverSocket.Accept();
                    clientSocket.Send(Encoding.UTF8.GetBytes("Server Say Hello"));
                    //没接收到一个连接,启动新线程接收数据
                    Thread receiveThread = new Thread(ReceiveMessage);
                    receiveThread.Start(clientSocket);
                }//while
            }//ListenClientConnection()
     
            /// <summary>
            /// 接收数据消息
            /// </summary>
            /// <param name="clientSocket">监听socket生成的普通通信socket</param>
            private static void ReceiveMessage(object clientSocket)
            { 
                Socket myClientSocket = (Socket)clientSocket;
                while (true)
                {
                    try
                    {
                        //通过myClientSocket接收数据
                        int receiveNumber = myClientSocket.Receive(buffer);
                        Console.WriteLine("接收客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(buffer, 0, receiveNumber));
                    }
                    catch(Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        //关闭所有的Socket连接功能Receive、Send、Both
                        myClientSocket.Shutdown(SocketShutdown.Both);
                        myClientSocket.Close();
                        break;
                    }
                }//while
            }//ReceiveMessage()
        }//class
    }

    客户端的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
     
    namespace ConsoleApplication7
    {
        class Program
        {
            private static byte[] buffer = new byte[1024];
     
            static void Main(string[] args)
            {
                //设定服务器ip地址
                IPAddress ip = IPAddress.Parse("127.0.0.1");
                Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                try 
                {
                    clientSocket.Connect(new IPEndPoint(ip, 8887));
                    Console.WriteLine("连接服务器成功");
                }
                catch(Exception ex)
                {
                    Console.WriteLine("服务器连接失败,请按回车退出");
                    return;
                }
     
                //通过clientSocket接收数据
                int receiveNumber = clientSocket.Receive(buffer);
                Console.WriteLine("接收服务器消息:{0}", Encoding.ASCII.GetString(buffer, 0, receiveNumber));
     
                //启动新的线程,给Server连续发送数据
                Thread sendThread = new Thread(SendMessage);
                //把线程设置为前台线程,不然Main退出了线程就会死亡
                sendThread.IsBackground = false;
                sendThread.Start(clientSocket);
     
            }//Main
     
            /// <summary>
            /// 启动新的线程,发送数据
            /// </summary>
            /// <param name="clientSocket"></param>
            private static void SendMessage(object clientSocket)
            {
                Socket sendSocket = (Socket)clientSocket;
                //利用新线程,通过sendSocket发送数据
                for (int i = 0; i < 100; i++)
                {
                    try
                    {
                        Thread.Sleep(1000);
                        string sendMessage = "client send Message Hellp" + DateTime.Now;
     
                        sendSocket.Send(Encoding.ASCII.GetBytes(sendMessage));
                        Console.WriteLine("向服务器发送消息:{0}", sendMessage);
     
                    }
                    catch (Exception ex)
                    {
                        sendSocket.Shutdown(SocketShutdown.Both);
                        sendSocket.Close();
                        //一旦出错,就结束循环
                        break;
                    }
                }//for
            }//SendMessage()
     
        }//class
    }

    代码总结:

    上面的代码没什么难点,就简单的说一下注意的地方:

    (1)字符串和字符数组之间的转换方法:Ecoding.UTF8.Get或者Ecoding.ASCII.Get这两个方法,很简单。但是当要把结构体和字符数组转换就没那么简单了。

    (2)客户端和服务器中启动了一些新的线程发送或者接收数据,在控制台,必须把线程设置为前台线程。不然Main函数一结束,就意味着主线程结束了,那么所有的后台线程就会随之死亡。

    (3)客户端发送数据的线程,不要在主线程中,因为它没隔10s发送一次数据,有Thread.sleep()函数的调用,在Main线程中会阻塞主线程,要单独的开一个线程发送数据。

    (4)在出现异常或者最后退出时,要关闭Socket的功能和关闭Socket的流。释放占用的计算机资源。

  • 相关阅读:
    软工15结对编程练习
    软件工程网络201521123108阅读作业2-提出问题
    软件工程网络15个人阅读作业1(201521123108 余腾鑫)
    java课程设计——算术运算测试个人博客
    java课程设计-算术运算测试
    201521123108《Java程序设计》第14周学习总结
    201521123108 《Java程序设计》第13周学习总结
    个人作业5——软工个人总结
    软工网络15个人作业4——alpha阶段个人总结
    软件工程网络15个人作业3——案例分析(201521123107)
  • 原文地址:https://www.cnblogs.com/stemon/p/4203877.html
Copyright © 2011-2022 走看看