C#.网络编程 Socket基础(一)Socket TCP协议 控制台 实现端到端(服务器与客户端)简单字符串通信

简介:

       本章节主要讨论了Socket的入门知识,还未针对Socket的难点问题(比如TCP的无消息边界问题)展开讨论,往后在其他章节中进行研究。

注意点

一、服务器(比如台式电脑)的IP为1.1.1.2,那么客户端(其他设备,比如手机,Ipad)连接的一定是服务器的IP,即也是1.1.1.2。这样才能建立起握手:

二、客户端的端口必须向服务器的端口看起。

三、必须先启动服务器,后启动客户端。

基础知识架构:

例子:

服务器code:

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
//服务器程序
namespace SocketServer
{
    class Program
    {
        private static byte[] result = new Byte[1024];
        private static int myprot = 8887;
        static Socket serverSocket;
        static int a = 0;
        static void Main(string[] args)
        {
            //服务器IP地址
            //IPAddress ip = IPAddress.Parse("127.0.0.1");
            IPAddress ip = IPAddress.Parse("194.168.1.124");
            //InterNetwork:IPv4。  Stream:流传输、数据不重发,一般不保留边界。
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);
            //IPEndPoint:IP和端口绑定后给Bind类,Bind类再给serverSocket。
            serverSocket.Bind(new IPEndPoint(ip, myprot));
            //启用侦听,最多能连接10客户端。
            serverSocket.Listen(10);
            //侦听成功后,输出本地的IP和端口号:LocalEndPoint是serverSocket的方法。
            Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
            Console.WriteLine("(位置1)主线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            //通过clientsocket发送数据。创建一个线程,用来连接客户端。
            Thread myThread = new Thread(ListenClientConnect);
            Console.WriteLine("(位置2)主线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            myThread.Start();
            Console.WriteLine("(位置3)主线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();
        }
        /// <summary>
        /// 接收连接
        /// </summary>
        private static void ListenClientConnect()
        {
            while (true)
            {
                Console.WriteLine("(位置1)ListenClientConnect线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                //Accept()表示服务器阻塞,等待客户端连接成功。若是连接成功,则返回客户端的IP和端口号、以及返回服务器的IP和端口号。
                //可以循环调用Accept(),连接不同的用户,从而响应不同的用户数。
                //int a = 0;
                //while ( (a<2) )
                //{
                Socket clientsocket = serverSocket.Accept();
                //服务器确认连接后,给客户端发送确认连接信息,表示双方已经握手成功。
                clientsocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));
                Console.WriteLine("(位置2)ListenClientConnect线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                //创建第三个线程,用来接收客户端信息。
                Thread receiveThread = new Thread(ReceiveMessage);
                Console.WriteLine("(位置3)ListenClientConnect线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                receiveThread.Start(clientsocket);
                Console.WriteLine("(位置4)ListenClientConnect线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                    //a++;
                //}
              
            }
        }
        /// <summary>
        /// 接收信息
        /// </summary>
        /// <param name="clientSocket">包含客户机信息的套接字</param>
        private static void ReceiveMessage(Object clientSocket)
        {
            Console.WriteLine("(位置1)ReceiveMessage线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            //创建一个包含客户端信息的类
            Socket myClientSocket = (Socket)clientSocket;
            Console.WriteLine("(位置2)ReceiveMessage线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            while (true)
            {
                try
                {
                    //通过clientsocket接收数据
                    Console.WriteLine("(位置3)ReceiveMessage线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                    //创建一个包含客户端信息的类,并用Receive接收客户端传输过来的信息,该信息放在result数组中。
                    int receiveNumber = myClientSocket.Receive(result);
                    //将int类型转换为字符串输出
                    Console.WriteLine("接收号客户端{0}消息{1}",myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
                    //Console.WriteLine("接收{0}号客户端{1}消息{2}",a,myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
                    Console.WriteLine("(位置4)ReceiveMessage线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("(位置5)ReceiveMessage线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                    Console.WriteLine(ex.Message);
                    Console.WriteLine("(位置6)ReceiveMessage线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                    myClientSocket.Shutdown(SocketShutdown.Both);
                    Console.WriteLine("(位置7)ReceiveMessage线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
                    myClientSocket.Close();
                    break;
                }
            }
        }
    }
}

客户端code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

//客户端程序
namespace SocketClient
{
    class Program
    {
        private static byte[] result = new Byte[1024];
        static void Main(string[] args)
        {
            //服务器IP地址
            //IPAddress ip = IPAddress.Parse("127.0.0.1");
            IPAddress ip = IPAddress.Parse("194.168.1.124");
            Socket clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
            try
            {
                //Connect表示客户端向服务器发起连接请求。而在服务端,用Accept()响应该请求。
                clientSocket.Connect(new IPEndPoint(ip, 8887));
                Console.WriteLine("连接服务器成功");
                
            }
            catch
            {
                Console.WriteLine("连接服务器失败,请按回车键退出");
                Console.Read();
                return;
            }
            //通过clientSocket接收数据。Receive表示接受服务器的数据。
            int receiveLength = clientSocket.Receive(result);
            Console.WriteLine("接收服务器消息:{0}",Encoding.ASCII.GetString(result, 0, receiveLength));
            // 通过clientSocket发送数据
            for (int i = 0; i < 15; i++)
            {
                try
                {
                    Thread.Sleep(1000);
                    string sendMessage = "(客户端1)client send Message Hello" + DateTime.Now;
                    //向武器器发送消息。
                    clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));
                    Console.WriteLine("(客户端1)向服务器发送消息:{0}", sendMessage);
                }
                catch
                {
                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close();
                    break;
                }
            }
            Console.WriteLine("发送完毕,按回车键退出");
            Console.ReadKey();
        }
    }
}

总结:

一、例程中发送的是字符串,往后将发送图片。

二、往后将建立基于WPF的工程项目。

猜你喜欢

转载自blog.csdn.net/xpj8888/article/details/83383355
今日推荐