精华内容
下载资源
问答
  • C#网络编程(Socket编程)

    千次阅读 多人点赞 2020-04-02 09:45:27
    一、Socket网络编程 1.Socket是什么? 在计算机通信领域,Socket被译为“套接字”。它是计算机之间进行通信的一种约定或一种方式。通过Socket这种约定可以接收到其他计算机的数据,也可以向其他计算机发送数据。 2....

    一、Socket网络编程

    1.Socket是什么?

    在计算机通信领域,Socket被译为“套接字”。它是计算机之间进行通信的一种约定或一种方式。通过Socket这种约定可以接收到其他计算机的数据,也可以向其他计算机发送数据。

    2.Socket本质

    编程接口(API),对于TCP/IP的封装,TCP/IP也提供了可供程序员做网络开发所用的接口

    3.Socket作用

    Socket的英文原意是“插座”,的意思,通常在计算机编程中称作套接字,可以用来实现不同虚拟机或不同计算机之间的通信

    4.Socket的典型应用

    (1)Socket的应用之一就是Web服务器和浏览器:浏览器获取用户输入的URL地址,向服务器发起请求,服务器分析接收到的URL请求,将对应的网页内容返回给浏览器,浏览器再经过解析和渲染,将文字、图片、视频等元素呈现给用户
    (2)QQ或者微信或者默默等聊天社交工具等:本地的QQ或微信程序就是客户端,登录过程就是连接服务器的过程,聊天过程就是Socket的发送和接受信息过程

    二、网络传输

    (一)OSI网络七层模型

    在这里插入图片描述

    特点:

    (1)人们可以很容易的讨论和学习协议的规范细节。
    (2)层间的标准接口方便了工程模块化。
    (3)创建了一个更好的互连环境。
    (4)降低了复杂度,使程序更容易修改,产品开发的速度更快。
    (5)每层利用紧邻的下层服务,更容易记住个层的功能。

    (二)网络模型

    网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机。
    现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈。
    在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)。客户端程序可以在需要的时候启动,而服务器为了能够时刻相应连接,则需要一直启动。例如以打电话为例,首先拨号的人类似于客户端,接听电话的人必须保持电话畅通类似于服务器。

    连接一旦建立以后,客户端和服务器端就可以进行数据传递了,而且两者的身份是等价的。

    在一些程序中,程序既有客户端功能也有服务器端功能,最常见的软件就是BT、emule这类软件了。

    (三)IP地址和端口

    1.IP地址

    IP地址是一个规定,现在使用的是IPv4,既由4个0-255之间的数字组成,在计算机内部存储时只需要4个字节即可。在计算机中,IP地址是分配给网卡的,每个网卡有一个唯一的IP地址,如果一个计算机有多个网卡,则该台计算机则拥有多个不同的IP地址,在同一个网络内部,IP地址不能相同。IP地址的概念类似于电话号码、身份证这样的概念。
    由于IP地址不方便记忆,所以有专门创造了 域名(Domain Name) 的概念,其实就是给IP取一个字符的名字,例如163.com、sina.com等。IP和域名之间存在一定的对应关系。如果把IP地址类比成身份证号的话,那么域名就是你的姓名。
    其实在网络中只能使用IP地址进行数据传输,所以在传输以前,需要把域名转换为IP,这个由称作DNS的服务器专门来完成
    所以在网络编程中,可以使用IP或域名来标识网络上的一台设备。

    2.端口

    可以认为是设备与外界通讯交流的出口。端口可分为虚拟端口和物理端口,其中虚拟端口指计算 机内部或交换机路由器内的端口,不可见。例如计算机中的80端口、21端口、23端口等。物理端口又称为接口,是可见端口,计算机背板的RJ45网口,交换机路由器集线器等RJ45端口。电话使用RJ11插口也属于物理端口的范畴。
    规定一个设备有216个,也就是65536个端口,每个端口对应一个唯一的程序。每个网络程序,无论是客户端还是服务器端,都对应一个或多个特定的端口号。由于0-1024之间多被操作系统占用 ,所以实际编程时一般采用1024以后的端口号

    (四)Socket/TCP五层网络模型

    在这里插入图片描述

    (五)TCP和UDP

    1.UDP:

    (1) 面向无连接,将数据及源封装在数据包中,不需要建立连接
    (2)每个数据报的大小限制在64K内
    (3)因无连接,是不可靠协议
    (4)不需要连接连接,速度快

    2.TCP:

    (1) 建立连接,形成传输数据的通道
    (2)在连接中进行大数据量传输,以字节流的形式
    (3)通过三次握手(四次挥手)完成连接,是可靠协议
    (4)必须建立连接,效率会稍低

    三、Socket/TCP

    TCP报文

    TCP报文是发送网络消息需要按照这种报文的格式去包装数据
    在这里插入图片描述

    一般需要了解一下几个字段:

    1. 序号:Seq序号,占32位,用来表示从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标识
    2. 确认序号:ACK序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ACK=Seq+1
    3. 标志位共六个:URGACKPSHRSTSYNFIN含义:
      (1)URG:紧急指针
      (2)ACK :确认序号有效
      (3)PSH:接收方应该尽快将这个报文交给应用层
      (4)RST:充值连接
      (5)SYN:发起一个新连接
      (6)FIN:释放一个连接
    4. 需要注意的是:
      (A)不要将确认序号Ack与标志位中的ACK搞混了。
      (B)确认方Ack=发起方Req+1,两端配对

    TCP三次握手

    所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:
    在这里插入图片描述

    第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SEND状态,等待Server确认。
    第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ACK=J+1,随机产生一个seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RECV状态。
    第三次握手:Client收到确认后,检查ACK是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ACK=K+1,并将数据包发送给Server,Server检查ACK是否为K+1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间就可以开始传输数据了。
    SYN攻击:在三次握手过程中,Server发送SYN-ACK后,收到Client的ACK之前的TCP连接称为半连接,此时Serve处于SYN_RECV状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断的发送SYN包,Server回复确认包,并等待Client的确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络阻塞甚至系统瘫痪。SYN攻击就是一种典型的DDOS攻击,检测SYN攻击方式也很简单,即当有大量半连接状态且源地址是随机的,则可以断定遭到SYN攻击了,使用如下命令让其无处可逃:netstat -nap|grep SYN_RECV

    TCP四次挥手

    所谓四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总发送三个包以确认连接的断开。在Socket编程中,这一过程由客户端或服务端任一方执行close来触发,流程如下:
    在这里插入图片描述

    由于TCP连接是全双工的,因此每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
    第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传输,Client进入FIN_WAIT_1状态。
    第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态
    第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传输,Server进入LAST_ACK状态
    第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手

    四、Socket编程

    (一)Socket编程方式

    Socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开Open->读写write/read->关闭close”模式来操作文件。Socket就是该模式的一个实现,Socket即是一种特殊的文件,一些Socket函数就是对其进行操作(读写IO、打开、关闭)。因此Socket也提供了类似于连接Connect、关闭连接Close、发送、接收等方法的调用

    (二)数据传输方式

    常用stream和dgram

    1. STREAM

    表示面向连接的数据传输方式,数据可以准确无误地到达另一台计算机,如果丢失或损坏,可以重新发送,但是相对效率低

    2.DGRAM

    表示无连接的数据传输方式,计算机只管数据传输不做数据校验,DGRAM所做的校验工作少,所以效率比STREAM高
    例如:QQ视频聊天和语音聊天使用的就是DGRAM传输数据,因为首先需要保证通信的效率,尽量减少延迟,而数据的正确性是次要的,即使丢失很小的一部分数据视频和音频也可以正常解析,最多出现噪点或杂音,不会对通信质量有实质影响

    (三)服务器端编写步骤

    1. 调用socket()函数创建一个用于通信的套接字
      买了个手机
    2. 给已经创建的套接字绑定一个端口号,一般通过设置网络套接口地址和调用bind()函数来实现
      办张手机卡,插上手机卡
    3. 调用listen()函数使套接字成为一个监听套接字
      等待来电
    4. 调用accept()函数来接受客户端的连接,这时就可以和客户端通信
      接听到了打来的电话
    5. 处理客户端的连接请求
      接通电话听、说沟通
    6. 终止连接
      挂断电话

    (四)客户端编写步骤

    1. 调用socket()函数创建一个用于通信的套接字
      买了个手机
    2. 通过设置套接字地址结构,说明客户端与之通信的服务器的IP地址和端口号
      输入对方手机号
    3. 调用Connect()函数来建立与服务器的连接
      拨号,并等接听
    4. 调用读写函数发送或接收数据
      说话、听话
    5. 终止连接
      挂断电话

    (五)案例

    服务器端

    在这里插入图片描述

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Net.Sockets;  //套接字的命名空间
    using System.Net; //IPAddress的命名空间
    using System.Threading; //线程的命名空间
    namespace FrmServer
    {
        public partial class 服务器 : Form
        {
            public 服务器()
            {
                InitializeComponent();
                toolStripStatusLabel1.Text = "服务器已关闭";
            }
            //1.1声明套接字
            Socket serverSocket = null;
            //3.2 创建用来专门作为监听来电等待工作的线程
            Thread listenThread = null;
            private void btnStartServer_Click(object sender, EventArgs e)
            {
                if (btnStartServer.Tag.ToString() == "open")
                {
                    btnStartServer.Tag = "close";
                    btnStartServer.Text = "关闭服务器";
                    //1.2调用Socket()函数 用于通信的套接字
                    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //第一个参数为寻找地址的方式,此时选定为IPV4的地址; 第二个参数为数据传输的方式,此时选择的是Stream传输(能够准确无误的将数据传输到);第三个参数为执行的协议,此时选择的是TCP协议;
                    //2.套接字绑定端口号,设置套接字的地址调用bind()因为此函数需要EndPoint 所以创建2.1和2.2
                    //2.1 设置地址  IPaddress 在using System.Net;下此时需引入
                    IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
                    //2.2 设置地址和端口
                    IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim())); //第一个参数为要设置的IP地址,第二参数为端口号
                    try
                    {
                        //2.套接字绑定端口号和IP
                        serverSocket.Bind(endPoint);
                        toolStripStatusLabel1.Text = "服务已开启!";
                        MessageBox.Show("开启服务成功", "开启服务");
                    }
                    catch (Exception ex)
                    {
    
                        MessageBox.Show("开启服务失败:" + ex.Message, "开启服务失败");//ex.Message为出现异常的消息
                        return;
                    }
                    //3.1监听套接字,等待
                    serverSocket.Listen(10); //参数为最大监听的用户数
                    listenThread = new Thread(ListenConnectSocket);
                    listenThread.IsBackground = true; //关闭后天线程
                    listenThread.Start();
                }
                else if (btnStartServer.Tag.ToString() == "close")
                {
                    toolStripStatusLabel1.Text = "服务器已关闭";
                    btnStartServer.Tag = "open";
                    btnStartServer.Text = "开启服务器";
                    isOpen = false;
                    serverSocket.Close();
                    serverSocket.Dispose();
                }
            }
            //3.3 用于判断用户是否链到服务器
            bool isOpen = true;  
            //3.4 监听用户来电 等待
           void ListenConnectSocket()
           {
                while (isOpen) 
                {
                    try
                    {
                        Socket ClientSocket = serverSocket.Accept();
                        byte[] buffer = Encoding.Default.GetBytes("成功连接到服务器!");
                        ClientSocket.Send(buffer); 
                        string client = ClientSocket.RemoteEndPoint.ToString();
                        listBox1.Invoke(new Action<string>((msg) =>
                        {
                            listBox1.Items.Add(DateTime.Now + ": " + msg);
                        }), client);
    
                        Thread thr = new Thread(ReceiveCkientMsg);
                        thr.IsBackground = true;
                        thr.Start(ClientSocket);
                    }
                    catch (Exception ex)
                    {
                        listenThread.Abort(ex.Message);
                    }
                }
           }
            /// <summary>
            /// 服务器解释用户消息
            /// </summary>
            /// <param name="clientSocket"></param>
            private void ReceiveCkientMsg(object clientSocket)
            {
                Socket client = clientSocket as Socket;
                while (true)
                {
                    byte[] recBuffer = new byte[1024 * 1024 * 2];
                    int length = -1;
                    try
                    {
                        length = client.Receive(recBuffer);
                    }
                    catch (Exception ex)
                    {
                        string str = client.RemoteEndPoint.ToString();
                        this.Invoke(new Action(() =>
                        {
                            listBox1.Items.Add($"{str}:{str}");
                            listBox1.Items.Remove(str);
                        }));
                        break;
                    }
                    if (length==0)
                    {
                        string str = client.RemoteEndPoint.ToString();
                        this.Invoke(new Action(() =>
                        {
                            listBox1.Items.Add($"{str}:下线了!");
                            listBox1.Items.Remove(str);
                        }));
                        break;
                    }
                    else
                    {
                        string msg = Encoding.Default.GetString(recBuffer,0, length);
                        string msgStr = $"{DateTime.Now}【接收{client.RemoteEndPoint.ToString()}】{msg}";
                        this.Invoke(new Action(() =>
                        {
                            txtReceive.AppendText(msgStr + Environment.NewLine);
                        }));
                    }
                }
            }
        }
    }
    

    在这里插入图片描述

    客户端

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    namespace FrmClient
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            //1.1创建套接字
            Socket clientSocket = null;
            Thread clientThread = null;
            //连接服务器
            private void btnConnectStart_Click(object sender, EventArgs e)
            {
                //1.2
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//地址类型,数据传输方式,协议
                //2.1 设置IP地址
                IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
                //2.2 设置IP地址和端口号
                IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
                try
                {
                    txtRecive.AppendText("与服务器连接中..." + Environment.NewLine);
                    //3与服务器建立连接
                    clientSocket.Connect(endPoint); // 与服务器连接
                }
                catch (Exception ex)
                {
                    MessageBox.Show("连接失败:"+ex.Message,"友情提示");
                    return;
                }
                txtRecive.AppendText("与服务器连接成功!" + Environment.NewLine);
                //4.接收或发送消息 使用线程来实现
                clientThread = new Thread(ReceiveMsg);
                clientThread.IsBackground = true; //开启后台线程
                clientThread.Start();
            }
    
            private void ReceiveMsg()
            {
                while (true)
                {
                    byte[] recBuffer = new byte[1024 * 1024 * 2];//声明最大字符内存
                    int length = -1; //字节长度
                    try
                    {
                        length = clientSocket.Receive(recBuffer);//返回接收到的实际的字节数量
                    }
                    catch (SocketException ex)
                    {
                        break;
                    }
                    catch (Exception ex)
                    {
                        this.Invoke(new Action(() =>
                        {
                            txtRecive.AppendText($"与服务器断开连接:{ex.Message}{Environment.NewLine}");
                        }));
                        break;
                    }
                    //接收到消息
                    if (length>0)
                    {
                        string msg = Encoding.Default.GetString(recBuffer, 0, length);//转译字符串(字符串,开始的索引,字符串长度)
                        string str = $"{DateTime.Now}【接收】{msg}{Environment.NewLine}";//接收的时间,内容,换行
                        this.Invoke(new Action(() =>
                        {
                            txtRecive.AppendText(str);//添加到文本
                        }));
                    }
                }
            }
            //发送消息
            private void btnSend_Click(object sender, EventArgs e)
            {
                string str = txtSendBox.Text.Trim();
                byte[] buffer = Encoding.Default.GetBytes(str);
                clientSocket.Send(buffer);
                this.Invoke(new Action(() =>
                {
                    txtRecive.AppendText($"{DateTime.Now}【发送】{str}{Environment.NewLine}");
                }));
            }  
        }
    }
    
    

    参考链接1
    参考链接2

    展开全文
  • 网络编程面试题(2020最新版)

    万次阅读 多人点赞 2020-03-16 17:36:28
    文章目录计算机网络体系结构网络协议是什么?为什么要对网络协议分层?TCP/IP 协议族应用层运输层网络层数据链路层物理层TCP/IP 协议族TCP的三次握手四次挥手TCP报文的头部结构三次握手四次挥手常见面试题为什么TCP...

    Java面试总结(2021优化版)已发布在个人微信公众号【技术人成长之路】,优化版首先修正了读者反馈的部分答案存在的错误,同时根据最新面试总结,删除了低频问题,添加了一些常见面试题,对文章进行了精简优化,欢迎大家关注!😊😊

    【技术人成长之路】,助力技术人成长!更多精彩文章第一时间在公众号发布哦!

    计算机网络体系结构

    在计算机网络的基本概念中,分层次的体系结构是最基本的。计算机网络体系结构的抽象概念较多,在学习时要多思考。这些概念对后面的学习很有帮助。

    网络协议是什么?

    在计算机网络要做到有条不紊地交换数据,就必须遵守一些事先约定好的规则,比如交换数据的格式、是否需要发送一个应答信息。这些规则被称为网络协议。

    为什么要对网络协议分层?

    • 简化问题难度和复杂度。由于各层之间独立,我们可以分割大问题为小问题。
    • 灵活性好。当其中一层的技术变化时,只要层间接口关系保持不变,其他层不受影响。
    • 易于实现和维护。
    • 促进标准化工作。分开后,每层功能可以相对简单地被描述。

    网络协议分层的缺点: 功能可能出现在多个层里,产生了额外开销。

    为了使不同体系结构的计算机网络都能互联,国际标准化组织 ISO 于1977年提出了一个试图使各种计算机在世界范围内互联成网的标准框架,即著名的开放系统互联基本参考模型 OSI/RM,简称为OSI。

    OSI 的七层协议体系结构的概念清楚,理论也较完整,但它既复杂又不实用,TCP/IP 体系结构则不同,但它现在却得到了非常广泛的应用。TCP/IP 是一个四层体系结构,它包含应用层,运输层,网际层和网络接口层(用网际层这个名字是强调这一层是为了解决不同网络的互连问题),不过从实质上讲,TCP/IP 只有最上面的三层,因为最下面的网络接口层并没有什么具体内容,因此在学习计算机网络的原理时往往采用折中的办法,即综合 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚,有时为了方便,也可把最底下两层称为网络接口层。

    四层协议,五层协议和七层协议的关系如下:

    • TCP/IP是一个四层的体系结构,主要包括:应用层、运输层、网际层和网络接口层。
    • 五层协议的体系结构主要包括:应用层、运输层、网络层,数据链路层和物理层。
    • OSI七层协议模型主要包括是:应用层(Application)、表示层(Presentation)、会话层(Session)、运输层(Transport)、网络层(Network)、数据链路层(Data Link)、物理层(Physical)。

    在这里插入图片描述

    注:五层协议的体系结构只是为了介绍网络原理而设计的,实际应用还是 TCP/IP 四层体系结构。

    TCP/IP 协议族

    应用层

    应用层( application-layer )的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。

    对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如域名系统 DNS,支持万维网应用的 HTTP 协议,支持电子邮件的 SMTP 协议等等。

    运输层

    运输层(transport layer)的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。

    运输层主要使用一下两种协议

    1. 传输控制协议-TCP:提供面向连接的,可靠的数据传输服务。
    2. 用户数据协议-UDP:提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
    UDPTCP
    是否连接无连接面向连接
    是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
    连接对象个数支持一对一,一对多,多对一和多对多交互通信只能是一对一通信
    传输方式面向报文面向字节流
    首部开销首部开销小,仅8字节首部最小20字节,最大60字节
    场景适用于实时应用(IP电话、视频会议、直播等)适用于要求可靠传输的应用,例如文件传输

    每一个应用层(TCP/IP参考模型的最高层)协议一般都会使用到两个传输层协议之一:

    运行在TCP协议上的协议:

    • HTTP(Hypertext Transfer Protocol,超文本传输协议),主要用于普通浏览。
    • HTTPS(HTTP over SSL,安全超文本传输协议),HTTP协议的安全版本。
    • FTP(File Transfer Protocol,文件传输协议),用于文件传输。
    • POP3(Post Office Protocol, version 3,邮局协议),收邮件用。
    • SMTP(Simple Mail Transfer Protocol,简单邮件传输协议),用来发送电子邮件。
    • TELNET(Teletype over the Network,网络电传),通过一个终端(terminal)登陆到网络。
    • SSH(Secure Shell,用于替代安全性差的TELNET),用于加密安全登陆用。

    运行在UDP协议上的协议:

    • BOOTP(Boot Protocol,启动协议),应用于无盘设备。
    • NTP(Network Time Protocol,网络时间协议),用于网络同步。
    • DHCP(Dynamic Host Configuration Protocol,动态主机配置协议),动态配置IP地址。

    运行在TCPUDP协议上:

    • DNS(Domain Name Service,域名服务),用于完成地址查找,邮件转发等工作。

    网络层

    网络层的任务就是选择合适的网间路由和交换结点,确保计算机通信的数据及时传送。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 IP 协议,因此分组也叫 IP 数据报 ,简称数据报。

    互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Intert Prococol)和许多路由选择协议,因此互联网的网络层也叫做网际层或 IP 层。

    数据链路层

    数据链路层(data link layer)通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。

    在两个相邻节点之间传送数据时,数据链路层将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。

    在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。

    一般的web应用的通信传输流是这样的:

    img

    发送端在层与层之间传输数据时,每经过一层时会被打上一个该层所属的首部信息。反之,接收端在层与层之间传输数据时,每经过一层时会把对应的首部信息去除。

    物理层

    在物理层上所传送的数据单位是比特。 物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。

    TCP/IP 协议族

    在互联网使用的各种协议中最重要和最著名的就是 TCP/IP 两个协议。现在人们经常提到的 TCP/IP 并不一定是单指 TCP 和 IP 这两个具体的协议,而往往是表示互联网所使用的整个 TCP/IP 协议族。

    img

    互联网协议套件(英语:Internet Protocol Suite,缩写IPS)是一个网络通讯模型,以及一整个网络传输协议家族,为网际网络的基础通讯架构。它常被通称为TCP/IP协议族(英语:TCP/IP Protocol Suite,或TCP/IP Protocols),简称TCP/IP。因为该协定家族的两个核心协定:TCP(传输控制协议)和IP(网际协议),为该家族中最早通过的标准。

    划重点:

    TCP(传输控制协议)和IP(网际协议) 是最先定义的两个核心协议,所以才统称为TCP/IP协议族

    TCP的三次握手四次挥手

    TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务端保存的一份关于对方的信息,如ip地址、端口号等。

    TCP可以看成是一种字节流,它会处理IP层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在TCP头部。

    一个TCP连接由一个4元组构成,分别是两个IP地址和两个端口号。一个TCP连接通常分为三个阶段:连接、数据传输、退出(关闭)。通过三次握手建立一个链接,通过四次挥手来关闭一个连接

    当一个连接被建立或被终止时,交换的报文段只包含TCP头部,而没有数据

    TCP报文的头部结构

    在了解TCP连接之前先来了解一下TCP报文的头部结构。

    TCPHeader.png

    上图中有几个字段需要重点介绍下:

    (1)序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。

    (2)确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。

    (3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:

    • ACK:确认序号有效。
    • FIN:释放一个连接。
    • PSH:接收方应该尽快将这个报文交给应用层。
    • RST:重置连接。
    • SYN:发起一个新连接。
    • URG:紧急指针(urgent pointer)有效。

    需要注意的是:

    • 不要将确认序号ack与标志位中的ACK搞混了。
    • 确认方ack=发起方seq+1,两端配对。

    三次握手

    三次握手的本质是确认通信双方收发数据的能力

    首先,我让信使运输一份信件给对方,对方收到了,那么他就知道了我的发件能力和他的收件能力是可以的

    于是他给我回信,我若收到了,我便知我的发件能力和他的收件能力是可以的,并且他的发件能力和我的收件能力是可以

    然而此时他还不知道他的发件能力和我的收件能力到底可不可以,于是我最后回馈一次,他若收到了,他便清楚了他的发件能力和我的收件能力是可以的

    这,就是三次握手,这样说,你理解了吗?

    三次握手.png

    • 第一次握手:客户端要向服务端发起连接请求,首先客户端随机生成一个起始序列号ISN(比如是100),那客户端向服务端发送的报文段包含SYN标志位(也就是SYN=1),序列号seq=100。
    • 第二次握手:服务端收到客户端发过来的报文后,发现SYN=1,知道这是一个连接请求,于是将客户端的起始序列号100存起来,并且随机生成一个服务端的起始序列号(比如是300)。然后给客户端回复一段报文,回复报文包含SYN和ACK标志(也就是SYN=1,ACK=1)、序列号seq=300、确认号ack=101(客户端发过来的序列号+1)。
    • 第三次握手:客户端收到服务端的回复后发现ACK=1并且ack=101,于是知道服务端已经收到了序列号为100的那段报文;同时发现SYN=1,知道了服务端同意了这次连接,于是就将服务端的序列号300给存下来。然后客户端再回复一段报文给服务端,报文包含ACK标志位(ACK=1)、ack=301(服务端序列号+1)、seq=101(第一次握手时发送报文是占据一个序列号的,所以这次seq就从101开始,需要注意的是不携带数据的ACK报文是不占据序列号的,所以后面第一次正式发送数据时seq还是101)。当服务端收到报文后发现ACK=1并且ack=301,就知道客户端收到序列号为300的报文了,就这样客户端和服务端通过TCP建立了连接。

    四次挥手

    四次挥手的目的是关闭一个连接

    四次挥手.jpeg

    比如客户端初始化的序列号ISA=100,服务端初始化的序列号ISA=300。TCP连接成功后客户端总共发送了1000个字节的数据,服务端在客户端发FIN报文前总共回复了2000个字节的数据。

    • 第一次挥手:当客户端的数据都传输完成后,客户端向服务端发出连接释放报文(当然数据没发完时也可以发送连接释放报文并停止发送数据),释放连接报文包含FIN标志位(FIN=1)、序列号seq=1101(100+1+1000,其中的1是建立连接时占的一个序列号)。需要注意的是客户端发出FIN报文段后只是不能发数据了,但是还可以正常收数据;另外FIN报文段即使不携带数据也要占据一个序列号。
    • 第二次挥手:服务端收到客户端发的FIN报文后给客户端回复确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=1102(客户端FIN报文序列号1101+1)、序列号seq=2300(300+2000)。此时服务端处于关闭等待状态,而不是立马给客户端发FIN报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。
    • 第三次挥手:服务端将最后数据(比如50个字节)发送完毕后就向客户端发出连接释放报文,报文包含FIN和ACK标志位(FIN=1,ACK=1)、确认号和第二次挥手一样ack=1102、序列号seq=2350(2300+50)。
    • 第四次挥手:客户端收到服务端发的FIN报文后,向服务端发出确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=2351、序列号seq=1102。注意客户端发出确认报文后不是立马释放TCP连接,而是要经过2MSL(最长报文段寿命的2倍时长)后才释放TCP连接。而服务端一旦收到客户端发出的确认报文就会立马释放TCP连接,所以服务端结束TCP连接的时间要比客户端早一些。

    常见面试题

    为什么TCP连接的时候是3次?2次不可以吗?

    因为需要考虑连接时丢包的问题,如果只握手2次,第二次握手时如果服务端发给客户端的确认报文段丢失,此时服务端已经准备好了收发数(可以理解服务端已经连接成功)据,而客户端一直没收到服务端的确认报文,所以客户端就不知道服务端是否已经准备好了(可以理解为客户端未连接成功),这种情况下客户端不会给服务端发数据,也会忽略服务端发过来的数据。

    如果是三次握手,即便发生丢包也不会有问题,比如如果第三次握手客户端发的确认ack报文丢失,服务端在一段时间内没有收到确认ack报文的话就会重新进行第二次握手,也就是服务端会重发SYN报文段,客户端收到重发的报文段后会再次给服务端发送确认ack报文。

    为什么TCP连接的时候是3次,关闭的时候却是4次?

    因为只有在客户端和服务端都没有数据要发送的时候才能断开TCP。而客户端发出FIN报文时只能保证客户端没有数据发了,服务端还有没有数据发客户端是不知道的。而服务端收到客户端的FIN报文后只能先回复客户端一个确认报文来告诉客户端我服务端已经收到你的FIN报文了,但我服务端还有一些数据没发完,等这些数据发完了服务端才能给客户端发FIN报文(所以不能一次性将确认报文和FIN报文发给客户端,就是这里多出来了一次)。

    为什么客户端发出第四次挥手的确认报文后要等2MSL的时间才能释放TCP连接?

    这里同样是要考虑丢包的问题,如果第四次挥手的报文丢失,服务端没收到确认ack报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是2MSL,所以需要等这么长时间来确认服务端确实已经收到了。

    如果已经建立了连接,但是客户端突然出现故障了怎么办?

    TCP设有一个保活计时器,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

    什么是HTTP,HTTP 与 HTTPS 的区别

    HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范

    区别HTTPHTTPS
    协议运行在 TCP 之上,明文传输,客户端与服务器端都无法验证对方的身份身披 SSL( Secure Socket Layer )外壳的 HTTP,运行于 SSL 上,SSL 运行于 TCP 之上, 是添加了加密和认证机制的 HTTP
    端口80443
    资源消耗较少由于加解密处理,会消耗更多的 CPU 和内存资源
    开销无需证书需要证书,而证书一般需要向认证机构购买
    加密机制共享密钥加密和公开密钥加密并用的混合加密机制
    安全性由于加密机制,安全性强

    常用HTTP状态码

    HTTP状态码表示客户端HTTP请求的返回结果、标识服务器处理是否正常、表明请求出现的错误等。

    状态码的类别:

    类别原因短语
    1XXInformational(信息性状态码) 接受的请求正在处理
    2XXSuccess(成功状态码) 请求正常处理完毕
    3XXRedirection(重定向状态码) 需要进行附加操作以完成请求
    4XXClient Error(客户端错误状态码) 服务器无法处理请求
    5XXServer Error(服务器错误状态码) 服务器处理请求出错

    常用HTTP状态码:

    2XX成功(这系列表明请求被正常处理了)
    200OK,表示从客户端发来的请求在服务器端被正确处理
    204No content,表示请求成功,但响应报文不含实体的主体部分
    206Partial Content,进行范围请求成功
    3XX重定向(表明浏览器要执行特殊处理)
    301moved permanently,永久性重定向,表示资源已被分配了新的 URL
    302found,临时性重定向,表示资源临时被分配了新的 URL
    303see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源(对于301/302/303响应,几乎所有浏览器都会删除报文主体并自动用GET重新请求)
    304not modified,表示服务器允许访问资源,但请求未满足条件的情况(与重定向无关)
    307temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
    4XX客户端错误
    400bad request,请求报文存在语法错误
    401unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
    403forbidden,表示对请求资源的访问被服务器拒绝,可在实体主体部分返回原因描述
    404not found,表示在服务器上没有找到请求的资源
    5XX服务器错误
    500internal sever error,表示服务器端在执行请求时发生了错误
    501Not Implemented,表示服务器不支持当前请求所需要的某个功能
    503service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

    GET和POST区别

    说道GET和POST,就不得不提HTTP协议,因为浏览器和服务器的交互是通过HTTP协议执行的,而GET和POST也是HTTP协议中的两种方法。

    HTTP全称为Hyper Text Transfer Protocol,中文翻译为超文本传输协议,目的是保证浏览器与服务器之间的通信。HTTP的工作方式是客户端与服务器之间的请求-应答协议。

    HTTP协议中定义了浏览器和服务器进行交互的不同方法,基本方法有4种,分别是GET,POST,PUT,DELETE。这四种方法可以理解为,对服务器资源的查,改,增,删。

    • GET:从服务器上获取数据,也就是所谓的查,仅仅是获取服务器资源,不进行修改。
    • POST:向服务器提交数据,这就涉及到了数据的更新,也就是更改服务器的数据。
    • PUT:英文含义是放置,也就是向服务器新添加数据,就是所谓的增。
    • DELETE:从字面意思也能看出,这种方式就是删除服务器数据的过程。

    GET和POST区别

    1. Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。 但是这种做法也不时绝对的,大部分人的做法也是按照上面的说法来的,但是也可以在get请求加上 request body,给 post请求带上 URL 参数。

    2. Get请求提交的url中的数据最多只能是2048字节,这个限制是浏览器或者服务器给添加的,http协议并没有对url长度进行限制,目的是为了保证服务器和浏览器能够正常运行,防止有人恶意发送请求。Post请求则没有大小限制。

    3. Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。

    4. Get执行效率却比Post方法好。Get是form提交的默认方法。

    5. GET产生一个TCP数据包;POST产生两个TCP数据包。

      对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

      而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

    什么是对称加密与非对称加密

    对称密钥加密是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方;

    而非对称加密是指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。
    由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,非常的慢

    什么是HTTP2

    HTTP2 可以提高了网页的性能。

    在 HTTP1 中浏览器限制了同一个域名下的请求数量(Chrome 下一般是六个),当在请求很多资源的时候,由于队头阻塞当浏览器达到最大请求数量时,剩余的资源需等待当前的六个请求完成后才能发起请求。

    HTTP2 中引入了多路复用的技术,这个技术可以只通过一个 TCP 连接就可以传输所有的请求数据。多路复用可以绕过浏览器限制同一个域名下的请求数量的问题,进而提高了网页的性能。

    Session、Cookie和Token的主要区别

    HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。

    什么是cookie

    cookie是由Web服务器保存在用户浏览器上的小文件(key-value格式),包含用户相关的信息。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户身份。

    什么是session

    session是依赖Cookie实现的。session是服务器端对象

    session 是浏览器和服务器会话过程中,服务器分配的一块储存空间。服务器默认为浏览器在cookie中设置 sessionid,浏览器在向服务器请求过程中传输 cookie 包含 sessionid ,服务器根据 sessionid 获取出会话中存储的信息,然后确定会话的身份信息。

    cookie与session区别

    • 存储位置与安全性:cookie数据存放在客户端上,安全性较差,session数据放在服务器上,安全性相对更高;
    • 存储空间:单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie,session无此限制
    • 占用服务器资源:session一定时间内保存在服务器上,当访问增多,占用服务器性能,考虑到服务器性能方面,应当使用cookie。

    什么是Token

    Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。

    Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。

    使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。

    Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位

    session与token区别

    • session机制存在服务器压力增大,CSRF跨站伪造请求攻击,扩展性不强等问题;
    • session存储在服务器端,token存储在客户端
    • token提供认证和授权功能,作为身份认证,token安全性比session好;
    • session这种会话存储方式方式只适用于客户端代码和服务端代码运行在同一台服务器上,token适用于项目级的前后端分离(前后端代码运行在不同的服务器下)

    Servlet是线程安全的吗

    Servlet不是线程安全的,多线程并发的读写会导致数据不同步的问题。

    解决的办法是尽量不要定义name属性,而是要把name变量分别定义在doGet()和doPost()方法内。虽然使用synchronized(name){}语句块可以解决问题,但是会造成线程的等待,不是很科学的办法。

    注意:多线程的并发的读写Servlet类属性会导致数据不同步。但是如果只是并发地读取属性而不写入,则不存在数据不同步的问题。因此Servlet里的只读属性最好定义为final类型的。

    Servlet接口中有哪些方法及Servlet生命周期探秘

    在Java Web程序中,Servlet主要负责接收用户请求HttpServletRequest,在doGet()doPost()中做相应的处理,并将回应HttpServletResponse反馈给用户。Servlet可以设置初始化参数,供Servlet内部使用。

    Servlet接口定义了5个方法,其中前三个方法与Servlet生命周期相关

    • void init(ServletConfig config) throws ServletException
    • void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException
    • void destory()
    • java.lang.String getServletInfo()
    • ServletConfig getServletConfig()

    生命周期:

    Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化;

    请求到达时调用Servlet的service()方法,service()方法会根据需要调用与请求对应的doGet或doPost等方法;

    当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy()方法

    init方法和destory方法只会执行一次,service方法客户端每次请求Servlet都会执行。Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init方法中,销毁资源的代码放入destroy方法中,这样就不需要每次处理客户端的请求都要初始化与销毁资源。

    如果客户端禁止 cookie 能实现 session 还能用吗?

    Cookie 与 Session,一般认为是两个独立的东西,Session采用的是在服务器端保持状态的方案,而Cookie采用的是在客户端保持状态的方案。

    但为什么禁用Cookie就不能得到Session呢?因为Session是用Session ID来确定当前对话所对应的服务器Session,而Session ID是通过Cookie来传递的,禁用Cookie相当于失去了Session ID,也就得不到Session了。

    假定用户关闭Cookie的情况下使用Session,其实现途径有以下几种:

    1. 手动通过URL传值、隐藏表单传递Session ID。
    2. 用文件、数据库等形式保存Session ID,在跨页过程中手动调用。
    展开全文
  • 网络编程基础及代码实现

    万次阅读 多人点赞 2018-09-06 16:51:44
    一、网络编程概述 1.计算机网络的相关概念 什么是计算机网络? 指分布在不同地域的计算机,通过外部设备连接起来,实现了资源共享(数据和设备的共享),实现数据传输的计算机系统。外部设备有:计算机、路由器、...

    一、网络编程概述

    1.计算机网络的相关概念

    什么是计算机网络?
    指分布在不同地域的计算机,通过外部设备连接起来,实现了资源共享(数据和设备的共享),实现数据传输的计算机系统。外部设备有:计算机、路由器、交换机等等。
    这里写图片描述

    什么是网络编程?
    网络编程关注的是数据的传输,在Java中又称为Socket编程。主要处理计算机与计算机之间的数据通信问题。

    计算机网络的三要素:
    IP地址:(家庭住址)是指互联网协议地址(Internet Protocol Address),是IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址。

    端口号:(门牌号)计算机中有很多软件与外界网络进行通信,每个通信的软件都会分配一个操作的端口号,用来区分不同的软件。

    协议:(快递的方式和格式)是网络上所有设备(网络服务器、计算机、交换机、路由器、防火墙等)之间通信规则的集合,它规定了通信时信息必须采用的格式和这些格式的意义,以及数据的传输方式等规定。

    资源的查找方式:
    通过IP地址找计算机,通过端口号找软件,通过协议来约定数据传输的格式
    这里写图片描述

    2.IP地址

    查看IP地址的DOS命令:ipconfig
    这里写图片描述
    检测网路是否连通的DOS命令:ping 对方的IP地址
    ping不通的结果:
    这里写图片描述
    ping通的结果:
    这里写图片描述
    IPV4的格式:
    Internet上的每台主机(Host)都有一个唯一的IP地址。IP地址的长度为32位二进制,分为4段,每段8位。使用十进制数字表示,则每段数字范围为0~255,段与段之间用句点隔开。例如159.226.1.1。(四个字节)
    1) 格式:网络号+主机号
    2) 分类:
    A类:网络号.主机号.主机号.主机号
    网络号占1个字节(0-127),主机号占3个字节。2^24 = 1677万
    B类: 网络号.网络号.主机号.主机号
    网络号占2个字节,主机号占2个字节。 16000多个网络,每个网络中的主机数是:65534
    C类:网络号.网络号.网络号.主机号
    网络号占3个字节,主机号占1个字节。200多万的网络,每个网络的主机数是254
    这里写图片描述
    IPV6的介绍:
    IPv4从理论上讲,编址1600万个网络、40亿台主机。但采用A、B、C三类编址方式后,可用的网络地址和主机地址的数目大打折扣,以至IP地址已于2011年2月3日分配完毕。其中北美占有3/4,约30亿个,而人口最多的亚洲只有不到4亿个,中国截止2010年6月IPv4地址数量达到2.5亿,落后于4.2亿网民的需求。地址不足,严重地制约了中国及其他国家互联网的应用和发展。

    IPv6具有更大的地址空间,IPv6中IP地址的长度为128位,即最大地址个数为2^128。分为8个16位的块。每个块,然后转换成由冒号分隔的4位十六进制数。如:2001:0000:3238:DFE1:0063:0000:0000:FEFB

    本机的IP地址:
    IPV4: 127.0.0.1 (点号分隔)
    IPV6: 0:0:0:0:0:0:0:1 (冒号分隔)

    3.端口号

    如果把IP地址比作一间房子 ,端口就是出入这间房子的门。真正的房子只有几个门,但是一个IP地址的端口 可以有65536(即:2^16)个之多!端口是通过端口号来标记的,端口号只有整数,范围是从0 到65535(2^16-1)。

    不同的软件通信,端口号不能相同,不能有冲突。
    这里写图片描述

    4.协议

    计算机之间又是如何交换信息的呢?就像我们说话用某种语言一样,在网络上的各台计算机之间也有语言,这就是网络协议,不同的计算机之间必须使用相同的网络协议才能进行通信。

    网络协议是网络上所有设备(网络服务器、计算机及交换机、路由器、防火墙等)之间通信规则的集合,它规定了通信时信息必须采用的格式和这些格式的意义。

    常用协议和端口号:
    这里写图片描述

    5.网络模型

    网络模型:是计算机网络通讯规范

    OSI(Open System Interconnection开放系统互连)模型:
    从上到下分七层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
    1) 应用层:老板
    2) 表示层:相当于公司中演示文稿、替老板写信的助理
    3) 会话层:相当于公司中收寄信、写信封与拆信封的秘书
    4) 传输层:相当于公司中跑邮局的送信职员
    5) 网络层:相当于邮局中的对邮件分类的工人
    6) 数据链路层:相当于邮局中的装拆箱工人
    7) 物理层:相当于邮局中的搬运工人
    这里写图片描述

    TCP/IP(Transmission Control Protocol/Internet Protocol 传输控制协议/互联网协议) 模型:
    分四层:应用层、传输层、网络层、网络接口层
    1) 应用层:应用层是应用程序间沟通的层,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等
    2) 传输层:使源端和目的端机器上可以进行会话。在这一层定义了两个端到端的协议:传输控制协议(TCP,Transmission Control Protocol)和用户数据报协议(UDP,User Datagram Protocol)。
    3) 网络层:主要解决主机到主机的通信问题。它所包含的协议设计数据包在整个网络上的逻辑传输。
    4) 网络接口层:它负责监视数据在主机和网络之间的交换。

    6.InetAddress类:

    java.net.InetAddress:
    此类表示互联网协议 (IP) 地址。IP 地址是 IP 使用的 32 位或 128 位无符号数字,它是一种低级协议,UDP 和 TCP 协议都是在它的基础上构建的。

    InetAddress类的方法:
    得到本机IP对象:

    //静态方法,会抛出UnknownHostException(不知道的主机异常)
    InetAddress address = InetAddress.getLocalHost();

    得到其它机器的IP对象:

    //通过IP地址的字符串
    //通过对方的主机名
    //通过域名
    InetAddress.getByName(String ip)

    得到IP地址的信息:

    //返回 IP 地址字符串(以文本表现形式)
    String getHostAddress()   
    //获取此 IP 地址的主机名
    String getHostName() 
    //返回此 InetAddress对象的原始 IP 地址,返回一个字节数组
    byte[] getAddress()  

    Demo示例:

    public class Demo1 {
        public static void main(String[] args) throws IOException {
          //得到主机:
          //得到自己的机器
          //InetAddress address = InetAddress.getLocalHost();
          //通过IP地址的字符串
          //InetAddress address = InetAddress.getByName("192.168.151.6");
          //通过主机名
          //InetAddress address = InetAddress.getByName("NEWBOY-PC"); 
          //通过域名  
          InetAddress address = InetAddress.getByName("www.163.com");  
          //输出IP地址
          System.out.println("IP地址是:" + address.getHostAddress());
          System.out.println("主机名是:" + address.getHostName());
          System.out.println("IP地址的字节表示:" + Arrays.toString(address.getAddress()));
        }
    }

    二、UDP协议

    1.UDP协议的特点:
    概念:User Datagram Protocol 用户数据报协议,以包的方式在网上传送数据,每个包都有传送和接受地址的讯息。
    1) 连接:发送数据不需创建连接,分为发送端和接收端。
    2) 大小:发送数据是以包为单位进行发送的,每个包的大小限制在64K
    3) 丢失:传输速度快,可能会造成数据丢失。
    4) 速度:相比TCP协议来说传输速度更快

    应用:视频通话, CS

    2.UDP类的API:
    使用到的类:

    java.net.DatagramSocket  //发送端或接收端
    java.net.DatagramPacket  //封装数据的包

    这里写图片描述
    发送端:
    1) 创建发送端DatagramSocket

    DatagramSocket() //将其绑定到本地主机上任何可用的端口。会抛出SocketException异常

    2) 创建数据包对象DatagramPacket

    //buf 字节数组:用来封装任意的二进制数据
    //length:数据的长度,length 参数必须小于等于 buf.length,一般与数组的长度相同
    //address:接收方的IP地址
    //port: 接收方的端口号
    DatagramPacket(byte[] buf, int length, InetAddress address, int port)      

    3) 发送方法

    void send(DatagramPacket p) //从此套接字发送数据报包 

    4) 关闭DatagramSocket

    void close() //关闭此数据报套接字

    接收端:
    1) 创建接收端DatagramSocket

    //创建数据报套接字并将其绑定到本地主机上的指定端口。端口号与发送端数据包中的端口号相同
    DatagramSocket(int port) 
    

    2) 创建数据包对象DatagramPacket

    //构造 DatagramPacket,用来接收长度为 length 的数据包
    DatagramPacket(byte[] buf, int length) 

    3) 接收方法:

    //从此套接字接收数据报包,这是一个阻塞型的方法,如果数据没有来,则一定等待
    void receive(DatagramPacket p)       

    4) 关闭DatagramSocket

    //关闭此数据报套接字
    void close()

    3.实现UDP的发送端和接收端

    #发送端
    public class UdpSender {
      public static void main(String[] args) throws IOException {
        System.out.println("发送端发出数据");
        //1) 创建发送端DatagramSocket,将其绑定到本地主机上任何可用的端口
        DatagramSocket socket = new DatagramSocket();
        //2) 创建数据包对象DatagramPacket
        byte[] buf = "你好,NewBoy!".getBytes();
        //创建接收方的IP地址对象和端口号
        InetAddress address = InetAddress.getByName("192.168.151.88");
        DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 9999);
        //3) 发送 socket.send(packet)
        socket.send(packet);
        //4) 关闭DatagramSocket
        socket.close();
      }
    }
    
    #接收端
    public class UdpReceiver {
      public static void main(String[] args) {
        System.out.println("接收端启动。。。");
        //1) 创建接收端DatagramSocket,本方的端口号
        try(DatagramSocket socket = new DatagramSocket(9999);) {
         //创建字节数组
         byte[] buf = new byte[1024];
         //2) 创建数据包对象DatagramPacket
         DatagramPacket packet = new DatagramPacket(buf, buf.length);
         //3) 接收,阻塞型的方法
         socket.receive(packet);
         //把数据输出
         byte[] data = packet.getData();   //从包中取出数据
         int len = packet.getLength();     //取出了长度
         //要求获取到发送者的IP地址和端口号
         InetAddress address = packet.getAddress();
         int port = packet.getPort();
         System.out.println("发送方的IP是:" + address + ",端口号:" + port);
         System.out.println("收到数据:" + new String(data,0,len));  
       } catch (IOException e) {
         e.printStackTrace();
       }
      }
    }

    4.UDP聊天大厅代码实现

    需求:使用UDP协议实现群聊的功能,发送信息和接收信息同时进行,输入端输入exit,则结束程序的运行。
    这里写图片描述
    1) 采用多线程的技术
    2) 创建一个线程发送方,在键盘输入信息。输入exit退出聊天室。
    3) 创建一个线程接收方,在控制台输出接收到的信息。
    4) 注:给一个网段中所有的用户发送信息使用IP广播地址:192.168.x.255

    #1.开启聊天功能
    public class ChatRoom {
      public static void main(String[] args) {
        System.out.println("聊天室开启");
        //开启发送端信息
        new ChatReceiver().start();
        //开启接收端信息
        new ChatSender().start();
      }
    }
    
    #2.发送端线程
    class ChatSender extends Thread {
      @Override
      public void run() {
        // 从键输入聊天的信息
        Scanner sc = new Scanner(System.in);
        // 创建发送端
        try (DatagramSocket socket = new DatagramSocket();) {
          // 声明包的对象
          DatagramPacket packet = null;
          while (true) {
            String words = sc.nextLine();
            if ("exit".equalsIgnoreCase(words)) {
              break;
            }
            else {
              // 创建包对象
              packet = new DatagramPacket(words.getBytes(), words.getBytes().length,InetAddress.getByName("192.168.59.255"), 8888);
              socket.send(packet);
            }           
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
         // 退出
         System.out.println("退出聊天室");
         System.exit(0);
      }
    }
    
    #3.接收端线程
    class ChatReceiver extends Thread {
      @Override
      public void run() {
        try (DatagramSocket socket = new DatagramSocket(8888);) {
          // 创建一个数组容器,存放数据
          byte[] buf = new byte[1024 * 2];
          DatagramPacket packet = new DatagramPacket(buf, buf.length);
          while (true) {
            // 开始接收
            socket.receive(packet);
            // 输出信息
            System.out.println(new Time(System.currentTimeMillis()) + "  " + packet.getAddress().getHostAddress() + "说:" + new String(packet.getData(), 0, packet.getLength()));
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

    三、TCP协议

    1.TCP协议的特点:
    1) 连接:数据传输可靠,传输之前需要创建连接。
    2) 大小:因为有连接,一旦连接成功,数据通过IO流的方式进行传输,可以传输无限大小的数据。
    3) C/S:有服务端和客户端之分,也就是平时所说的C/S(Client / Server)结构。
    4) 速度:相比UDP协议,传输速度更慢。

    2.TCP的API:
    客户端: Socket类(套接字)
    1) 构造方法:

    Socket(String host, int port)  
    Socket(InetAddress address, int port) //指定服务端的主机名(或IP地址)和端口号

    2) 方法:

    void close() //关闭此套接字。 
    InputStream getInputStream() //返回此套接字的输入流。 如果从输入流中读取数据,就相当于接收信息。
    OutputStream getOutputStream() //返回此套接字的输出流。 如果向输出流中写入数据,就相当于发送信息。

    服务端: ServerSocket类
    1) 构造方法:

    ServerSocket(int port) //创建绑定到特定端口的服务器套接字,这个端口号是本机的端口号,不能有冲突。

    2) 关闭此套接字

    void close()

    3.为什么ServerSocket服务端类没有得到输入输出流的方法?

    Socket accept() //是一个阻塞型的方法,每来一个客户端,就创建一个Socket对象与其对应,进行数据的通信

    这里写图片描述

    3.实现客户端与服务端之间的通信

    这里写图片描述

    #1.客户端向服务器端发送一条数据
    public class TcpClient {
       public static void main(String[] args) {
         // 1.创建Socket
         try (Socket socket = new Socket("192.168.151.88", 9898);
             // 2. 发送数据,得到输出流
             OutputStream os = socket.getOutputStream();
             InputStream is = socket.getInputStream();) {
           // 3.写数据
           os.write("你好,我是客户端!".getBytes());
           // 创建字节数组
           byte[] buf = new byte[1024];
          // 接收服务端发回的数据
           int len = is.read(buf);
           System.out.println(new String(buf, 0, len));
         } catch (IOException e) {
           e.printStackTrace();
         }
       }
     }
    
    #2.服务端也向客户端发送一条数据回应 
    public class TcpServer {
      public static void main(String[] args) {
        System.out.println("服务器启动。。。");
        //创建ServerSocket对象
        try(ServerSocket serverSocket = new ServerSocket(9898);) {
          //等待客户端的连接
          Socket socket = serverSocket.accept();
          //创建输入流,读取
          InputStream is = socket.getInputStream();
          OutputStream os = socket.getOutputStream();  //发送
          byte[] buf = new byte[1024];
          int len = is.read(buf);  //读取客户端发送过来的数据
          System.out.println("服务器收到客户端的信息:" + new String(buf,0,len));
          //发送信息回客户端
          os.write("你好,我是服务端,收到你的消息!".getBytes());
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

    4.实现服务端循环读取客户端发送的数据

    需求:
    1) 客户端和服务端都使用键盘输入的方式,把信息发送给对方。
    2) 使用字符流的方式,处理字符数据更加方便。
    3) BufferedReader中readLine();读取一行数据,使用BufferedWriter write(“字符串的数据”) 写数据

    2.技术要点:
    1) 因为字符流有缓存,所以如果要发送数据到对方的话,需要flush(),如果没有调用flush()会导致数据发送失败,对方无法收到数据。
    2) 写入数据给对方,一定要换行,调用newLine(),否则对方无法使用readLine()读取到数据。

    #1.客户端代码
    public class ChatClient {
      public static void main(String[] args) {
        // 创建Socket对象
        try (Scanner sc = new Scanner(System.in);
            Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
            // 字符输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 字符输出流
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));) {
          while (true) {
            System.out.println("我说:");
            // 接收键盘的输入字符串
            String words = sc.nextLine();
            if ("exit".equals(words)) {
              break;
            }
            // 发送数据
            bw.write(words);
            // 换行
            bw.newLine();
            // 一定要flush()
            bw.flush();
            // 收取对方的数据
            System.out.println("对方说:" + br.readLine());
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }  
    
    #2.服务端代码
    public class ChatServer {
      public static void main(String[] args) {
        System.out.println("服务端启动。。。");
        //创建服务端
        try(
            Scanner sc = new Scanner(System.in);
            ServerSocket serverSocket = new ServerSocket(8888);
            //得到客户端对应的对象
            Socket socket = serverSocket.accept();  
            // 字符输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 字符输出流
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            ) {
          while(true) {
            //接收对方的数据
            System.out.println("客户端说:" + br.readLine());
            System.out.println("我说:");
            String words = sc.nextLine();
            if ("exit".equals(words)) {  //只要说了exit,结束循环
              break;
            }
            //发送给对方
            bw.write(words);
            bw.newLine();
            bw.flush();
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    } 

    5.实现从服务器端下载一张图片文件

    需求:编写一个TCP的服务端,可以接受多个客户端的连接,当接收到用户的连接请求以后,就要把一张图片传回给客户端。

    分析:如果有一个用户连接上了,还在传输文件的过程中,又有新的用户连接,则会受到影响,所以要用到多线程的知识。每个用户使用一个专门的线程来服务,1对多的关系。
    这里写图片描述
    要点:
    1) 只需创建一个ServerSocket对象
    2) 每次accpet()得到一个Socket对象以后,通过构造方法传入到多线程类中,创建一个新的线程。
    3) 多线程类的run方法读取本地服务器端的文件,通过字节流的方式写入到客户端中。
    4) 注意:文件发送完成以后,是不会发送-1过去的,所以对方无法结束。需要调用方法:socket.shutdownOutput()

    #1.服务器端代码
    public class ImageServer extends Thread {
      private Socket socket;
    
      //创建一个带参数的构造方法
      public ImageServer(Socket socket) {
        this.socket = socket;
      }
    
      @Override
      public void run() {
        //读取图片文件
        try(FileInputStream fis = new FileInputStream("d:/girl.jpg");  //文件的输入流
          OutputStream os = socket.getOutputStream();    //网络输出流
            ) {
          //创建字节数组
          byte[] buf = new byte[1024 * 4];
          int len = 0;
          while((len = fis.read(buf))!=-1) {   
            os.write(buf, 0, len);
          }
          //关闭输出流
          socket.shutdownOutput();
          System.out.println(now() + "\t" +  socket.getInetAddress().getHostAddress() + " 下载完成");
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    
      /**
       * 得到当前的时间
       */
      public static String now() {
        return new Timestamp(System.currentTimeMillis()).toString();
      }
    
      //启动程序
      public static void main(String[] args) {
        System.out.println(now() + " 启动图片服务器");
        //创建一个ServerSocket对象
        try(ServerSocket serverSocket = new ServerSocket(9876);) {
          while (true) {
            //每次accpet()得到一个Socket对象以后,通过构造方法传入到多线程类中。
            Socket socket = serverSocket.accept();
            //得到IP地址
            InetAddress address = socket.getInetAddress();
            //输出连接的信息
            System.out.println(now() + "\t" + address.getHostAddress() + " 开始下载图片");
            //开启一个线程
            new ImageServer(socket).start();
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }  
    
    #2.客户端
    public class ImageClient {
      public static void main(String[] args) {
        //创建客户端
        try(Socket socket = new Socket("192.168.151.88", 9876);
          //网络的输入流
          InputStream is = socket.getInputStream();
          //文件的输出流
          FileOutputStream fos = new FileOutputStream("e:/a.jpg");  
            ) {
          byte[] buf = new byte[1024];
          int len = 0;
          //服务器端必须要shutdownOutput这里才能读取到-1
          while((len = is.read(buf))!=-1) {
            fos.write(buf,0,len);
          }
          System.out.println("图片下载成功");
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    展开全文
  • 前面介绍了网络编程的相关基础知识,初步建立了网络编程的概念,但是实际学习网络编程还必须使用某种程序设计语言进行代码实现,下面就介绍一下网络编程的代码实现。   1.2.1 网络编程步骤 按照前面的基础知识...

    1.2 网络编程技术

    前面介绍了网络编程的相关基础知识,初步建立了网络编程的概念,但是实际学习网络编程还必须使用某种程序设计语言进行代码实现,下面就介绍一下网络编程的代码实现。

     

    1.2.1 网络编程步骤

    按照前面的基础知识介绍,无论使用TCP方式还是UDP方式进行网络通讯,网络编程都是由客户端和服务器端组成。当然,B/S结构的编程中只需要实现服务器端即可。所以,下面介绍网络编程的步骤时,均以C/S结构为基础进行介绍。

    说明:这里的步骤实现和语言无关,也就是说,这个步骤适用于各种语言实现,不局限于Java语言。

     

    1.2.1.1 客户端网络编程步骤

    客户端(Client)是指网络编程中首先发起连接的程序,客户端一般实现程序界面和基本逻辑实现,在进行实际的客户端编程时,无论客户端复杂还是简单,以及客户端实现的方式,客户端的编程主要由三个步骤实现:

    1、 建立网络连接

    客户端网络编程的第一步都是建立网络连接。在建立网络连接时需要指定连接到的服务器的IP地址和端口号,建立完成以后,会形成一条虚拟的连接,后续的操作就可以通过该连接实现数据交换了。

     

    2、 交换数据

    连接建立以后,就可以通过这个连接交换数据了。交换数据严格按照请求响应模型进行,由客户端发送一个请求数据到服务器,服务器反馈一个响应数据给客户端,如果客户端不发送请求则服务器端就不响应。

    根据逻辑需要,可以多次交换数据,但是还是必须遵循请求响应模型。

     

    3、 关闭网络连接

    在数据交换完成以后,关闭网络连接,释放程序占用的端口、内存等系统资源,结束网络编程。

    最基本的步骤一般都是这三个步骤,在实际实现时,步骤2会出现重复,在进行代码组织时,由于网络编程是比较耗时的操作,所以一般开启专门的现场进行网络通讯。

     

    1.2.1.2 服务器端网络编程步骤

    服务器端(Server)是指在网络编程中被动等待连接的程序,服务器端一般实现程序的核心逻辑以及数据存储等核心功能。服务器端的编程步骤和客户端不同,是由四个步骤实现,依次是:

    1、 监听端口

    服务器端属于被动等待连接,所以服务器端启动以后,不需要发起连接,而只需要监听本地计算机的某个固定端口即可。

    这个端口就是服务器端开放给客户端的端口,服务器端程序运行的本地计算机的IP地址就是服务器端程序的IP地址。

     

    2、 获得连接

    当客户端连接到服务器端时,服务器端就可以获得一个连接,这个连接包含客户端的信息,例如客户端IP地址等等,服务器端和客户端也通过该连接进行数据交换。

    一般在服务器端编程中,当获得连接时,需要开启专门的线程处理该连接,每个连接都由独立的线程实现。

     

    3、 交换数据

    服务器端通过获得的连接进行数据交换。服务器端的数据交换步骤是首先接收客户端发送过来的数据,然后进行逻辑处理,再把处理以后的结果数据发送给客户端。简单来说,就是先接收再发送,这个和客户端的数据交换数序不同。

    其实,服务器端获得的连接和客户端连接是一样的,只是数据交换的步骤不同。

    当然,服务器端的数据交换也是可以多次进行的。

    在数据交换完成以后,关闭和客户端的连接。

     

    4、 关闭连接

    当服务器程序关闭时,需要关闭服务器端,通过关闭服务器端使得服务器监听的端口以及占用的内存可以释放出来,实现了连接的关闭。

    其实服务器端编程的模型和呼叫中心的实现是类似的,例如移动的客服电话10086就是典型的呼叫中心,当一个用户拨打10086时,转接给一个专门的客服人员,由该客服实现和该用户的问题解决,当另外一个用户拨打10086时,则转接给另一个客服,实现问题解决,依次类推。

    在服务器端编程时,10086这个电话号码就类似于服务器端的端口号码,每个用户就相当于一个客户端程序,每个客服人员就相当于服务器端启动的专门和客户端连接的线程,每个线程都是独立进行交互的。

    这就是服务器端编程的模型,只是TCP方式是需要建立连接的,对于服务器端的压力比较大,而UDP是不需要建立连接的,对于服务器端的压力比较小罢了。

     

    1.2.1.3 小结

    总之,无论使用任何语言,任何方式进行基础的网络编程,都必须遵循固定的步骤进行操作,在熟悉了这些步骤以后,可以根据需要进行逻辑上的处理,但是还是必须遵循固定的步骤进行。

    其实,基础的网络编程本身不难,也不需要很多的基础网络知识,只是由于编程的基础功能都已经由API实现,而且需要按照固定的步骤进行,所以在入门时有一定的门槛,希望下面的内容能够将你快速的带入网络编程技术的大门。

     

     

    展开全文
  • 网络编程的一般步骤

    千次阅读 2017-05-23 17:19:51
    对于TCP连接: 1.服务器端1)创建套接字create;2)绑定端口号bind;3)监听连接listen;4)接受连接请求accept,并返回新的套接字;5)用新返回的套接字recv/send;6)关闭套接字。...Server端
  • Java 网络编程

    万次阅读 多人点赞 2019-05-30 23:07:18
    网络编程 一、网络编程基础概念 首先理清一个概念:网络编程不等于网站编程,网络编程即使用套接字来达到进程间通信,现在一般称为TCP/IP编程。 计算机网络: 把分布在不同地理区域的计算机与专门的外部设备用通信...
  • IOS网络编程与云端应用最佳实践,完整扫描版

    千次下载 热门讨论 2014-10-11 21:57:18
    《清华开发者书库:iOS网络编程与云端应用最佳实践》是介绍iOS 6网络编程和云端应用开发技术书籍,介绍了苹果网络、数据交换格式、Web Service、iCloud、定位服务、地图、推送通知、Newsstand、应用内购买、Passbook...
  • 《MATLAB神经网络编程》 化学工业出版社 读书笔记 第六章反馈型神经网络 6.1 Hopfield网络 本文是《MATLAB神经网络编程》书籍的阅读笔记,其中涉及的源码、公式、原理都来自此书,若有不理解之处请参阅原书 前馈...
  • 150讲轻松学习Python网络爬虫

    万人学习 2019-05-16 15:30:54
    比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站 【课程设计】 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: 网络请求:模拟浏览器的行为从网上抓取...
  • Java网络编程实现

    万次阅读 多人点赞 2018-10-14 12:17:06
    网络程序的数据交互则依赖于TCP/IP协议,在实际应用中TCP网络程序提供可靠的数据通信,而UDP网络程序则不保证数据的可靠性,但是协议简单、传输速度快(比如用在音视频数据传输,它们不需要很高的可靠性,偶尔丢帧是...
  • 正常情况下我们需要对下位机进行通信需要使用Socket进行连接操作,而在网络编程中又分为面向连接(TCP)和面向无连接(UDP)这两种,针对这两种方式,我们不做具体的原理解释,只说各自的特点和各自的应用场景: ...
  • 《MATLAB神经网络编程》 化学工业出版社 读书笔记 第四章 前向型神经网络 4.3 BP传播网络本文是《MATLAB神经网络编程》书籍的阅读笔记,其中涉及的源码、公式、原理都来自此书,若有不理解之处请参阅原书 本文讲述...
  • C#多线程和Socket网络编程精讲

    千人学习 2019-08-04 20:08:47
    2、教学过程实例丰富、强调技术关键点、并且分析透彻  3、物美价廉:本着知识共享、服务社会宗旨,诣在为更多有需求者提供服务。  此外,提供源代码+答疑+上课讲义,为学生毕业设计、找工作面试等提供...
  • Java网络编程

    千次阅读 多人点赞 2020-11-28 17:29:17
    Java网络编程 1、网络编程 1.1、概述 1、计算机网络是通过传输介质、通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来,实现资源共享和数据传输的系统。网络编程就就是编写程序使联网的两个(或多个)...
  • 网络编程十宗罪

    万次阅读 多人点赞 2021-11-14 01:21:57
    文章目录1、TCP没考虑粘包分包2、UDP没考虑丢包3、长连接没考虑应用层心跳4、大数据没考虑分片和流量控制5、客户端没考虑断线重连6、外网没考虑加密通信7...很多同学面试时对书上的话背诵如流,在实际TCP编程中却没有处
  • 老曹眼中的网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为我们拥有网络。网络是一个神奇的东西,它改变了你和我的生活方式,改变了整个世界。 然而,网络的无标度...
  • 什么是网络编程(一)

    万次阅读 多人点赞 2018-12-30 00:12:26
    1.什么是网络、计算机网络的构成是什么?  在计算领域中,网络是传输信息、接受、...网络编程从大的方面就是说对信息的发送接收。 通过操作相应API调度计算机资源硬件,并且利用管道(网线)进行数据交互的过程。...
  • Python网络编程(socket编程)

    万次阅读 多人点赞 2018-05-13 14:28:38
    Win10python - 3.5 Socket工作原理和基本概念 Socket的中文翻译是套接字,它是TCP/IP网络环境下应用程序与底层通信驱动程序之间运行的开发接口,它可以将应用程序与具体的TCP/IP隔离开来,使得应用程序不需要了解...
  • Python神经网络编程(一)之神经网络如何工作

    万次阅读 多人点赞 2018-12-22 10:06:16
    Python神经网络编程 之前说过要转深度学习这块的,导师push的紧,只能摸石头过河,一方面阅读一些相关书籍,一方面跑一些模型修改源码去解决实际的问题。今天给大家介绍一本Python神经网络编程,今年4月份出版的:...
  • Linux C网络编程基础

    千次阅读 2018-08-12 16:23:09
    Linux C的网络基础操作函数 字节顺序转换函数族 IP地址转换函数族 域名转换函数 Linux网络套接字操作函数 创建套接字描述符函数 绑定套接字函数 建立连接函数 倾听套接字切换函数 接收连接函数 关闭连接...
  • python3_实现BP神经网络 + BP神经网络应用实例

    万次阅读 多人点赞 2018-07-29 22:10:28
    1.BP神经网络简介 BP神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照逆向传播算法训练的多层前馈神经网络,是目前应用最广泛的神经网络。 优点:具有任意复杂的模式分类能力和优良的...
  • 网络编程基础

    万次阅读 2017-05-20 12:25:46
    网络编程的模型 每一个网络应用基本都是由一个服务器进程和一个或多个客户端进程组成.服务器负责管理某种资源,如ftp服务器负责管理一组磁盘文件,web服务器负责管理一些动态或静态资源.网络编程的模型也就是"客户端-...
  • 《iOS网络编程与云端应用最佳实践》源码

    千次下载 热门讨论 2013-05-21 10:02:15
    《iOS网络编程与云端应用最佳实践》是介绍iOS 6网络编程和云端应用开发技术书籍,介绍了苹果网络、数据交换格式、WebService、iCloud、定位服务、地图、推送通知、Newsstand、应用内购买、Passbook、以及社交网络...
  • 网络编程和套接字 网络编程其实和我们计算机上的文件读取操作很类似,通俗地讲,网络编程就是编写程序使两台联网的计算机相互交换数据。那么,数据具体怎么传输呢?其实操作系统会提供名为“套接字”的部件,套接字...
  • windows网络编程

    千次阅读 2018-05-31 22:04:10
    Winsock是windows系统下利用Socket套接字进行网络编程的相关函数,是Windows下的网络编程接口。 Winsock在常见的Windows平台上有两个主要的版本,即Winsock1和Winsock2。编写与Winsock1兼容的程序你需要引用头文件...
  • Java网络编程总结

    万次阅读 多人点赞 2016-09-22 11:26:57
    本文主要对java网络编程Socket类的使用做总结,其中Socket对象可以进行数据的读取和写入是必须要知道的!
  • 即时通讯网论坛里精心整理了《[通俗易懂]深入理解TCP协议》、《不为人知的网络编程》、《P2P技术详解》、《高性能网络编程》这几个网络编程的系列文章,甚至还有图文并貌+实战代码的《NIO框架入门》等等。...
  • Linux网络编程 宋敬彬 孙海滨

    热门讨论 2011-12-09 16:49:20
    第2篇 Linux用户层网络编程 第5章 TCP/IP协议族简介 138 5.1 OSI网络分层介绍 138 5.1.1 OSI网络分层结构 138 5.1.2 OSI的7层网络结构 139 5.1.3 OSI参考模型中的数据传输 140 5.2 TCP/IP协议栈 141 ...
  • java网络编程面试题

    万次阅读 2017-08-08 11:59:26
    java网络编程面试题
  • Java网络编程详解

    万次阅读 多人点赞 2014-09-10 17:55:34
    1、网络编程 网络编程  网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习。  在 学习网络编程以前...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 534,917
精华内容 213,966
关键字:

网络编程的过程