Socket/TCP协议学习记录(一)--- 概念

学习地址 http://www.sikiedu.com/course/63/task/1478/show

IP和端口号 

ip 找到电脑地址

同一个路由器,分配过去电脑的ip就是局域网ip,dos系统输入ipconfig能搜索自己电脑的局域网ip,在百度搜索ip会弹出本机的外网ip

端口号  使用设定的软件访问电脑,所以每个软件的端口号也是唯一的

一般知名的端口号在0-1023,而我们经常使用的自定义/动态分配的端口号则一般在49152-65535之间

不要申请公认的端口,例如80

为了不跟别的软件产生端口冲突,我们可以查看电脑各个软件使用的端口:https://jingyan.baidu.com/article/fec7a1e5f944211190b4e719.html

TCP的三次握手,四次挥手

建立连接的时候需要经过三次握手进行连接,然后断开连接的时候需要经过四次挥手进行断开连接

创建服务器端

1使用ip4地址,2使用数据流,使用tcp协议

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;  //必须引入的命名空间
using System.Net;

namespace TCP服务器端
{
    class Program
    {
        static void Main(string[] args)
        {
                                                //ip地址                 //使用数据流       //指定使用的协议
            Socket serverSokect = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //本机10.66.20.118   本机ip   万能本地ip 127.0.0.1,,当你客户端进行连接的时候就要连接服务的ip
            //IPAdress 就是ip地址,,ipEndPoint 就是代表 “ip:端口号”
            IPAddress ipAdress = IPAddress.Parse("10.66.20.118");  //创建一个ip地址
            IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, 88);   //申请一个端口号
            serverSokect.Bind(ipEndPoint);   //申请完了端口号和ip地址,绑定到服务端

            serverSokect.Listen(0);     //一次性允许处理的监听,如果设置10个,就是我的队列里面一次性只对10个客户端进行数据监听
                                        //0个的话就是不限制,这个数据不是代表允许连接的数量,是代表处理连接的队列
            Socket clientSocket=serverSokect.Accept();    //接受一个客户端的连接,程序在这个时候会暂停,直到有一个客户端进行了连接
            string msg = "hello client!  你好";
            byte[] data=System.Text.Encoding.UTF8.GetBytes(msg);    //在进行网络传输的时候,只能传输字节,就是0和1这些数据,所以我们
                                                                  //要把字符串转成byte数组传输出去
            clientSocket.Send(data);    //这样我就向客户端发送一条消息


            //接收到客户端发来的消息
            byte[] dataBuffer = new byte[1024];    //创建一个缓冲区,1024是确保一般大小的数据长度满足
            int count= clientSocket.Receive(dataBuffer);   //获取接收到数据的长度
            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer,0,count);  //这样就把传进来的数据转化为string 
                                                                                          //从第几个dataBuffer的第几个数据进行截取,这个参数必须指定的
            Console.WriteLine("客户端的消息:"+msg);
           
            clientSocket.Close();   //这个只是关闭跟客户端的连接
            serverSokect.Close();    //这个是关闭服务器自身的连接

        }
    }
}

创建一个客户端

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

namespace TCP客户端
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///这个是创建一个客户端,这个跟服务器的创建是一样的
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("10.66.20.118"), 88));//这样就跟服务器端进行了指定的ip和端口号进行了连接
            
            ///这样我们首先接收一下服务器端的消息
            byte[] dataBuffer = new byte[1024];
            int count = clientSocket.Receive(dataBuffer);
            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);
            Console.WriteLine(msgReceive);

            //向客户端发送一条消息
            string s = Console.ReadLine();    //等待输入
            clientSocket.Send(Encoding.UTF8.GetBytes(s));   //转成数据0,1进行发送
            clientSocket.Close();    //关闭客户端

        }
    }
}

实行服务器异步接收消息

服务器端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;  //必须引入的命名空间
using System.Net;

namespace TCP服务器端
{
    class Program
    {
        static void Main(string[] args)
        {
            startServerAsync();
            Console.ReadKey();
        }


        /// <summary>
        /// 异步接收数据
        /// </summary>
        static void startServerAsync()
        {

            //ip地址                 //使用数据流       //指定使用的协议
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //本机10.66.20.118   本机ip   万能本地ip 127.0.0.1,,当你客户端进行连接的时候就要连接服务的ip
            //IPAdress 就是ip地址,,ipEndPoint 就是代表 “ip:端口号”
            IPAddress ipAdress = IPAddress.Parse("10.66.20.118");  //创建一个ip地址
            IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, 88);   //申请一个端口号
            serverSocket.Bind(ipEndPoint);   //申请完了端口号和ip地址,绑定到服务端

            serverSocket.Listen(0);     //一次性允许处理的监听,如果设置10个,就是我的队列里面一次性只对10个客户端进行数据监听
                                        //0个的话就是不限制,这个数据不是代表允许连接的数量,是代表处理连接的队列
                                        //Socket clientSocket = serverSokect.Accept();    //接受一个客户端的连接,程序在这个时候会暂停,直到有一个客户端进行了连接

            //表示开始监听数据的接收
            serverSocket.BeginAccept(AcceptCallBack, serverSocket);
        }


        static byte[] dataBuffer = new byte[1024];
        /// <summary>
        /// 当我们接收到一条消息的时候我们会用这个方法去处理
        /// </summary>
        /// <param name="ar"></param>
        static void ReceiveCallBack(IAsyncResult ar)
        {
            Socket clientSocket=null;
            try    //创建异常捕捉
            {
                clientSocket = ar.AsyncState as Socket;
                int count = clientSocket.EndReceive(ar);  //可以知道接收的消息有多长
                if (count == 0) {

                    clientSocket.Close();
                    return;
                }
                string msg = Encoding.UTF8.GetString(dataBuffer, 0, count); //这个完成接收
                Console.WriteLine("从客户端接收到的消息:" + msg);
                clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);  //函数递归回调
            }
            catch (Exception e)
            {
                Console.WriteLine(e);

                if (clientSocket != null)
                {

                    clientSocket.Close();
                }

            }                    
        }


        static void AcceptCallBack(IAsyncResult ar) {
            Socket serverSocket = ar.AsyncState as Socket;
            Socket clientSocket=serverSocket.EndAccept(ar);
            string msg = "hello client!  你好";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg);
            clientSocket.Send(data);
            clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
            serverSocket.BeginAccept(AcceptCallBack, serverSocket);
        }

        /// <summary>
        /// 这是一个同步消息的服务端发送
        /// </summary>
        void startServerSync()
        {

            //ip地址                 //使用数据流       //指定使用的协议
            Socket serverSokect = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //本机10.66.20.118   本机ip   万能本地ip 127.0.0.1,,当你客户端进行连接的时候就要连接服务的ip
            //IPAdress 就是ip地址,,ipEndPoint 就是代表 “ip:端口号”
            IPAddress ipAdress = IPAddress.Parse("10.66.20.118");  //创建一个ip地址
            IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, 88);   //申请一个端口号
            serverSokect.Bind(ipEndPoint);   //申请完了端口号和ip地址,绑定到服务端

            serverSokect.Listen(0);     //一次性允许处理的监听,如果设置10个,就是我的队列里面一次性只对10个客户端进行数据监听
                                        //0个的话就是不限制,这个数据不是代表允许连接的数量,是代表处理连接的队列
            Socket clientSocket = serverSokect.Accept();    //接受一个客户端的连接,程序在这个时候会暂停,直到有一个客户端进行了连接
            string msg = "hello client!  你好";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg);    //在进行网络传输的时候,只能传输字节,就是0和1这些数据,所以我们
                                                                      //要把字符串转成byte数组传输出去
            clientSocket.Send(data);    //这样我就向客户端发送一条消息


            //接收到客户端发来的消息
            byte[] dataBuffer = new byte[1024];    //创建一个缓冲区,1024是确保一般大小的数据长度满足
            int count = clientSocket.Receive(dataBuffer);   //获取接收到数据的长度
            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);  //这样就把传进来的数据转化为string 
                                                                                            //从第几个dataBuffer的第几个数据进行截取,这个参数必须指定的
            Console.WriteLine("客户端的消息:" + msgReceive);


            Console.ReadKey();
            clientSocket.Close();   //这个只是关闭跟客户端的连接
            serverSokect.Close();    //这个是关闭服务器自身的连接

        }
    }
}

客户端

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

namespace TCP客户端
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///这个是创建一个客户端,这个跟服务器的创建是一样的
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("10.66.20.118"), 88));//这样就跟服务器端进行了指定的ip和端口号进行了连接
            
            ///这样我们首先接收一下服务器端的消息
            byte[] dataBuffer = new byte[1024];
            int count = clientSocket.Receive(dataBuffer);
            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);
            Console.WriteLine(msgReceive);
            while (true) {

                string s = Console.ReadLine();    //等待输入

                if (s == "c") {

                    clientSocket.Close(); return;

                }
                clientSocket.Send(Encoding.UTF8.GetBytes(s));   //转成数据0,1进行发送
            }
            //向客户端发送一条消息           
            Console.ReadKey();
            clientSocket.Close();    //关闭客户端

        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一丁目赠我

谢谢你的打赏,感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值