• Socket


    1、基于TCP的web服务器

      windows控制台应用程序

    class Program
        {
            static void Main(string[] args)
            {
                //SocketServer();
                GetClientMsg();
                //TcpServer();
            }
    
            private static void SocketServer()
            {
                // 获得本机的Ip地址,即127.0.0.1
                IPAddress localaddress =IPAddress.Loopback;
                
                // 创建可以访问的断点,49155表示端口号,如果这里设置为0,表示使用一个由系统分配的空闲的端口号
                IPEndPoint endpoint = new IPEndPoint(localaddress,49155);
    
                // 创建Socket对象,使用IPv4地址,数据通信类型为数据流,传输控制协议TCP协议.
                Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
                
                //将Socket绑定到断点上
                socket.Bind(endpoint);
                // 设置连接队列的长度
                socket.Listen(10);
    
                while (true)
                {
                    Console.WriteLine("Wait an connect Request...");
                    // 开始监听,这个方法会堵塞线程的执行,直到接受到一个客户端的连接请求
                    Socket clientsocket =socket.Accept();
                    
                    // 输出客户端的地址
                    Console.WriteLine("Client Address is: {0}", clientsocket.RemoteEndPoint);
                    // 把客户端的请求数据读入保存到一个数组中
                    byte[] buffer =new byte[2048];
    
                    int receivelength = clientsocket.Receive(buffer, 2048, SocketFlags.None);
                    string requeststring = Encoding.UTF8.GetString(buffer, 0, receivelength);
                    
                    // 在服务器端输出请求的消息
                    Console.WriteLine(requeststring);
    
                    // 服务器端做出相应内容
                    // 响应的状态行
                    string statusLine ="HTTP/1.1 200 OK\r\n";
                    byte[] responseStatusLineBytes = Encoding.UTF8.GetBytes(statusLine);
                    string responseBody = "<html><head><title>Default Page</title></head><body><p style='font:bold;font-size:24pt'>Welcome you</p></body></html>";
                    string responseHeader = 
                        string.Format(
                            "Content-Type: text/html; charset=UTf-8\r\nContent-Length: {0}\r\n",responseBody.Length);
    
                    byte[] responseHeaderBytes = Encoding.UTF8.GetBytes(responseHeader);
                    byte[] responseBodyBytes = Encoding.UTF8.GetBytes(responseBody);
    
                    // 向客户端发送状态行
                    clientsocket.Send(responseStatusLineBytes);
    
                    // 向客户端发送回应头信息
                    clientsocket.Send(responseHeaderBytes);
    
                    // 发送头部和内容的空行
                    clientsocket.Send(new byte[] { 13, 10 });
    
                    // 想客户端发送主体部分
                    clientsocket.Send(responseBodyBytes);
    
                    // 断开连接
                    clientsocket.Close();
                    Console.ReadKey();
                    break;                                         
                }
                
                // 关闭服务器
                socket.Close();
    
            }
    
            private static void TcpServer()
            {
                // 获得本机的Ip地址,即127.0.0.1
                IPAddress localaddress = IPAddress.Loopback;
    
                // 创建可以访问的断点,49155表示端口号,如果这里设置为0,表示使用一个由系统分配的空闲的端口号
                IPEndPoint endpoint = new IPEndPoint(localaddress, 49155);
    
                // 创建Tcp 监听器
                TcpListener tcpListener = new TcpListener(endpoint);
    
                // 启动监听
                tcpListener.Start();
                Console.WriteLine("Wait an connect Request...");
                while (true)
                {
                    // 等待客户连接
                    TcpClient client = tcpListener.AcceptTcpClient();
                    if (client.Connected == true)
                    {
                        // 输出已经建立连接
                        Console.WriteLine("Created connection");
                    }
    
                    // 获得一个网络流对象
                    // 该网络流对象封装了Socket的输入和输出操作
                    // 此时通过对网络流对象进行写入来返回响应消息
                    // 通过对网络流对象进行读取来获得请求消息
                    NetworkStream netstream = client.GetStream();
                    // 把客户端的请求数据读入保存到一个数组中
                    byte[] buffer = new byte[2048];
    
                    int receivelength = netstream.Read(buffer, 0, 2048);
                    string requeststring = Encoding.UTF8.GetString(buffer, 0, receivelength);
    
                    // 在服务器端输出请求的消息
                    Console.WriteLine(requeststring);
    
                    // 服务器端做出相应内容
                    // 响应的状态行
                    string statusLine = "HTTP/1.1 200 OK\r\n";
                    byte[] responseStatusLineBytes = Encoding.UTF8.GetBytes(statusLine);
                    string responseBody = "<html><head><title>Default Page</title></head><body><p style='font:bold;font-size:24pt'>Welcome you</p></body></html>";
                    string responseHeader =
                        string.Format(
                            "Content-Type: text/html; charset=UTf-8\r\nContent-Length: {0}\r\n", responseBody.Length);
    
                    byte[] responseHeaderBytes = Encoding.UTF8.GetBytes(responseHeader);
                    byte[] responseBodyBytes = Encoding.UTF8.GetBytes(responseBody);
    
                    // 写入状态行信息
                    netstream.Write(responseStatusLineBytes, 0, responseStatusLineBytes.Length);
                    // 写入回应的头部
                    netstream.Write(responseHeaderBytes, 0, responseHeaderBytes.Length);
                    // 写入回应头部和内容之间的空行
                    netstream.Write(new byte[] { 13, 10 }, 0, 2);
    
                    // 写入回应的内容
                    netstream.Write(responseBodyBytes, 0, responseBodyBytes.Length);
    
                    // 关闭与客户端的连接
                    client.Close();
                    
                }
    
                // 关闭服务器
                //tcpListener.Stop();
            }
    
            private static void GetClientMsg()
            {
                TcpListener listener = new TcpListener(IPAddress.Any, 1300);
                listener.Start();
                while (true)
                {
                    Console.WriteLine("start listen");
                    TcpClient client = listener.AcceptTcpClient();
                    NetworkStream stream = client.GetStream();
                    byte[] buffer = new byte[128];
                    stream.Read(buffer, 0, buffer.Length);
                    string text = System.Text.Encoding.UTF8.GetString(buffer);
                    Console.WriteLine(text);
                    client.Close();
                }
            }
        }

    2、基于socket的局域网聊天程序

      界面如下:

      

    本地会启动一个socket来监听访问,点击按钮会启用一个socket来发送消息,为发送消息的socket端口占用,每次会检查是否端口占用。

        public partial class SocketChatForm : Form
        {
            private int serverPort = 1347;
            Thread listenThread = null;
            Thread sendThread = null;
            Socket acceptClient = null;
    
            private IPAddress TargetIP
            {
                get 
                {
                    string ip = "127.0.0.1";
                    if (!string.IsNullOrEmpty(tbIP.Text.Trim()))
                    {
                        ip = tbIP.Text.Trim();
                    }
                    return IPAddress.Parse(ip);
                }
            }
    
            public SocketChatForm()
            {
                InitializeComponent();
                listenThread = new Thread(new ThreadStart(ReceiveMsg));
                listenThread.Start();
            }
    
            private void btnSend_Click(object sender, EventArgs e)
            {
                sendThread = new Thread(new ThreadStart(SendMsg));
                sendThread.Start();
            }
    
            private void SendMsg()
            {
                Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                int clientPort = new Random().Next(10000);
                while (PortInUse(clientPort))
                {
                    clientPort = new Random().Next(10000);
                }
                IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Loopback, clientPort);
                socketClient.Bind(localEndpoint);
    
                IPEndPoint remoteEndpoint = new IPEndPoint(TargetIP, serverPort);
    
                string text = tbMsg.Text.Trim();
                if (string.IsNullOrEmpty(text))
                { return; }
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(text);
    
                try
                {
                    socketClient.Connect(remoteEndpoint);
                }
                catch { MessageBox.Show("无法连接到目标地址"); return; }
                socketClient.Send(buffer);
                socketClient.Close();
                this.Invoke(new MsgHandler(SetText), string.Empty);
                sendThread.Abort();
            }
    
            private void ReceiveMsg()
            {
                Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint endpoint = new IPEndPoint(IPAddress.Loopback, serverPort);
                socketServer.Bind(endpoint);
                socketServer.Listen(10);
                while (true)
                {
                    acceptClient = socketServer.Accept();
                    byte[] buffer = new byte[256];
                    int len = acceptClient.Receive(buffer);
                    string text = System.Text.Encoding.UTF8.GetString(buffer);
                    this.Invoke(new MsgHandler(AddListView), text);
                    acceptClient.Close();
                    acceptClient = null;
                }
            }
    
            private delegate void MsgHandler(string msg);
    
            private void AddListView(string msg)
            {
                listBox1.Items.Add(msg);
            }
    
            private void SetText(string msg)
            {
                tbMsg.Text = msg;
            }
    
            /// <summary>
            /// 检查端口号是否被占用
            /// </summary>
            /// <param name="port"></param>
            /// <returns></returns>
            public static bool PortInUse(int port)
            {
                bool inUse = false;
    
                IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
                IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
    
                foreach (IPEndPoint endPoint in ipEndPoints)
                {
                    if (endPoint.Port == port)
                    {
                        inUse = true;
                        break;
                    }
                }
                ipProperties = null;
                return inUse;
            }
    
        }

    当然也可以用TcpClient和TcpListener来实现。或者使用无连接的UDP来实现。

    3、关闭窗口时有些资源没有释放导致进程一直挂起。可以在Dispose方法中加入System.Environment.Exit(0);来退出进程

  • 相关阅读:
    第二阶段站立会议第十天
    第二阶段站立会议第九天
    第二阶段站立会议第八天
    第二阶段站立会议第七天
    第二阶段站立会议第六天
    第二阶段站立会议第五天
    第二阶段站立会议第四天
    第二冲刺阶段个人进度10
    第二冲刺阶段个人进度09
    第二冲刺阶段个人进度08
  • 原文地址:https://www.cnblogs.com/xingbinggong/p/2584947.html
Copyright © 2020-2023  润新知