zoukankan      html  css  js  c++  java
  • socket入门教程

    Server.cs   服务端程序

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    using System.Net;
    using System.Net.Sockets;
    
    namespace SocketTest
    {
        public partial class Server : Form
        {
            Thread serverThread; //服务端线程
            Thread clientThread; //客户端线程
            Socket serverSocket; //服务端socket
            Socket clientSocket; //客户端socket
    
            public Server()
            {
                InitializeComponent();
            }
    
            private void ServerStart()
            {
                //创建IPEndPoint实例
                IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 6001);
                //创建一个套接字
                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //将所创建的套接字与IPEndPoint绑定
                serverSocket.Bind(ipep);
                //设置套接字为收听模式
                serverSocket.Listen(10);
    
                /**
                 * 通过serverSocket.Accept()来接收客户Socket的连接请求,
                 * 在这里用循环可以实现该线程实时侦听,而不是只侦听一次。
                 * 当程序运行serverSocket.Accept()时,会等待,直到有客户端Socket发起连接请求时,
                 * 获取该客户Socket,如上面的clientSocket。在这里我用多线程来实现与多个客户端Socket的连接和通信,
                 * 一旦接收到一个连接后,就新建一个线程,执行ReceiveData功能来实现信息的发送和接收。
                 */
                while (true)
                {
                    try
                    {
                        //在套接字上接收接入的连接
                        clientSocket = serverSocket.Accept();
                        clientThread = new Thread(new ThreadStart(ReceiveData));
                        clientThread.Start();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("listening Error: " + ex.Message);
                    }
                }
            }
    
            /**
             * 通过IPEndPoint clientep = (IPEndPoint)s.RemoteEndPoint;
             * 我们可以获取连接上的远程主机的端口和IP地址,如果想查询该主机的其它属性如主机名等,
             * 可用于上一篇讲的Dns.GetHostByAddress(string ipAddress)来返回一个IPHostEntry对象,就可以得到。
             * 另外我们要注意的是,通过Socket发送信息,必须要先把发送的信息转化成二进字进行传输,
             * 收到信息后也要把收到的二进字信息转化成字符形式,
             * 这里可以通过Encoding.ASCII.GetBytes(welcome);和Encoding.ASCII.GetString(buffer).Substring(0, bufLen);来实现。
             * 以上就是服务端Socket侦听模式的实现,只要有远程客户端Socket连接上后,就可以轻松的发送信息和接收信息了。
             * 下面我们来看看客户端Socket是怎么连接上服务器的。
             **/
            private void ReceiveData()
            {
                bool keepalive = true;
                Socket s = clientSocket;
                Byte[] buffer = new Byte[1024];
                //根据收听到的客户端套接字向客户端发送信息
                IPEndPoint clientep = (IPEndPoint)s.RemoteEndPoint;
                this.Invoke(new MethodInvoker(() =>
                {
                    lstServer.Items.Add("Client:" + clientep.Address + "(" + clientep.Port + ")");
                }));
                string welcome = "Welcome to my test sever ";
                byte[] data = new byte[1024];
                data = Encoding.ASCII.GetBytes(welcome);
                s.Send(data, data.Length, SocketFlags.None);
                while (keepalive)
                {
                    //在套接字上接收客户端发送的信息
                    int bufLen = 0;
                    try
                    {
                        bufLen = s.Available;
                        s.Receive(buffer, 0, bufLen, SocketFlags.None);
                        if (bufLen == 0)
                            continue;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Receive Error:" + ex.Message);
                        return;
                    }
                    clientep = (IPEndPoint)s.RemoteEndPoint;
                    string clientcommand = System.Text.Encoding.ASCII.GetString(buffer).Substring(0, bufLen);
                    this.Invoke(new MethodInvoker(() =>
                    {
                        lstServer.Items.Add(clientcommand + "(" + clientep.Address + ":" + clientep.Port + ")");
                    }));
                }
            }
    
            private void btnOpen_Click(object sender, EventArgs e)
            {
                serverThread = new Thread(new ThreadStart(ServerStart));
                serverThread.Start();
                lstServer.Items.Add("Server Start .....");
            }
        }
    }

    Client.cs(客户端程序)

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    
    namespace Client
    {
        public partial class Client : Form
        {
            Socket clientSocket;
            Thread clientThread;
    
            public Client()
            {
                InitializeComponent();
            }
    
            /**
             * 客户端Socket连接相对来说比较简单了,另外说明一下,在执行客户端连接前,服务端Socket侦听必须先启动,
             * 不然会提示服务器拒绝连接的信息。
             * 客户端的发送信息和接收信息跟服务器的接收发送是一样的,只不过一个是侦听模式而另一个是连接模式。
             * 另外提一下,这里服务端开启侦听服务、客户端连接服务端都采用线程方式来实现,这样服务端能够跟多个客户端同时通信,不用等候,
             * 当然还有另外一种方式可以实现那就是异步socket.
             */
            private void ConnectToServer()
            {
                byte[] data = new byte[1024];
                //创建一个套接字
                IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6001);
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //将套接字与远程服务器地址相连
                try
                {
                    clientSocket.Connect(ipep);
                }
                catch (SocketException ex)
                {
                    MessageBox.Show("connect error: " + ex.Message);
                    return;
                }
                while (true)
                {
                    //接收服务器信息
                    int bufLen = 0;
                    try
                    {
                        bufLen = clientSocket.Available;
                        clientSocket.Receive(data, 0, bufLen, SocketFlags.None);
                        if (bufLen == 0)
                        {
                            continue;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Receive Error:" + ex.Message);
                        return;
                    }
                    string clientcommand = System.Text.Encoding.ASCII.GetString(data).Substring(0, bufLen);
                    this.Invoke(new MethodInvoker(() =>
                    {
                        lstClient.Items.Add(clientcommand);
                    }));
                    //clientSocket.Shutdown(SocketShutdown.Both);
                    //clientSocket.Close();
                }
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                clientThread = new Thread(new ThreadStart(ConnectToServer));
                clientThread.Start();
            }
    
            private void btnSend_Click(object sender, EventArgs e)
            {
                //向服务器发送信息
                byte[] data = new byte[1024];
                data = Encoding.ASCII.GetBytes(txtClient.Text);
                clientSocket.Send(data, data.Length, SocketFlags.None);
            }
        }
    }
  • 相关阅读:
    206.反转链表
    gprof
    Java【Stream流、方法引用】学习笔记
    Java【函数式接口(Supplier、Comsumer、Predicate、Function)】学习笔记
    Python exec 内置语句
    Python sorted() 函数
    Python oct() 函数
    Python id() 函数
    Python dir() 函数
    软件测试的方法
  • 原文地址:https://www.cnblogs.com/systemnet123/p/3237833.html
Copyright © 2011-2022 走看看