初学java网络编程的一些总结

*软件的结构:

服务器:提供信息的计算机或程序;

客户机:请求信息的计算机或程序;

网络:由若干节点和连接这些节点的链路构成,表示诸多对象及其相互联系它用于连接服务器与客户机,实现两者的相互通信

注意:(某些网络中很难将服务器和客户机区分开)

1.c/s(client/server)结构:
在这里插入图片描述
2.b/s(browser/server)结构:在这里插入图片描述
B/S架构和C/S架构的区别有:C/S一般建立在专用的网络上,是小范围里的网络环境,通过专门服务器提供连接和数据交换服务;一般面向相对固定的用户群,对信息安全的控制能力很强。B/S 建立在广域网之上的,不必有专门的网络硬件环境;面向是不可知的用户群,对安全的控制能力相对弱。

咱们讲的通俗易懂点,我们使用QQ只需要访问腾讯的QQ服务器,而我们通过浏览器,可以访问官方的网站,个人搭建的博客(二者的服务器很明显是不同的)…多的比我女朋友还多。

可见2种架构各有优势,但都需要网络的支持,而我们讲的网络编程就是在一定的协议下,实现2台计算机通信的程序

网络通信协议:是一种网络通用语言,为连接不同操作系统和不同硬件体系结构的互联网络引提供通信支持,是一种网络通用语言。

例如,网络中一个微机用户和一个大型主机的操作员进行通信,由于这两个数据终端所用字符集不同,因此操作员所输入的命令彼此不认识。为了能进行通信,规定每个终端都要将各自字符集中的字符先变换为标准字符集的字符后,才进入网络传送,到达目的终端之后,再变换为该终端字符集的字符。因此,网络通信协议也可以理解为网络上各台计算机之间进行交流的一种语言,它对数据传输的格式,速率,步骤做了统一的规定。放在现实中,如果一个软件只能发送英文,而你和你的朋友,一个只会汉语(打个比方,没有冒犯的意思),一个只会日语,你们要通过该软件进行交流,你必须先把汉语翻译成英语才能发给他,他需要把英语翻译成日语才能读懂你的信息。


tcp/ip(Transmission Control Protocol/internet Protocol)协议(TCP/IP协议簇):是Internet最基本最广泛的协议,它定义了计算机如何连入因特网,以及数据如何在他们之间传输的标准,它的内部包含了一系列的用于处理数据通信的协议,并采用了4层的分层模式
(注意它不是一个协议而是一堆协议,我们取其中的两个协议命名,一个是TCP ,一个IP。)
在这里插入图片描述


这个我们了解即可,我们的重点放在传输层。

tcp:是一种以固接连线(客户端和服务器端必须经过三次握手建立逻辑连接,才能通信)为基础的协议,它提供两台计算机间可靠的数据传送。TCP可以保证从一端数据送至连接的另一端时,数据能够确实送达,而且抵达的数据的排列顺序和送出时的顺序相同。因此,TCP协议适合可靠性要求比较高的场合。就像拨打电话,必须先拨号给对方,等两端确定连接后,相互才能听到对方说话,也知道对方回应的是什么。(说的通俗易懂点,一个单词只有在其字母顺序正确的情况下才能表示这个单词,如果顺序错了,则不能表达其原意)

udp:是无连接通信协议,不保证数据的可靠传输,但能够向若干个目标发送数据,或接收来自若干个源的数据。UDP以独立发送数据包的方式进行。这种方式就像邮递员送信给收信人,可以寄出很多信给同一个人,且每一封信都是相对独立的,各封信送达的顺序并不重要,收信人接收信件的顺序也不能保证与寄出信件的顺序相同。

UDP协议适合于一些对数据准确性要求不高对传输速度和时效性要求非常高的网站,如网络聊天室、在线影片等。这是由于TCP协议在认证上存在额外耗费,可能使传输速度减慢,而UDP协议即使有一小部分数据包遗失或传送顺序有所不同,也不会严重危害该项通信。

总结一下:
tcp:
①数据的传输是有序的
②数据的传输是有确认机制的
③有数据重传机制
④可靠性的前提是建立一条连接

udp:
①数据的传输是无序的
②数据的传输是无确认机制的
③无数据重传机制
④无需建立一条连接
(请记住 我特别快)


tcp/ip tcp完了下面我们介绍下ip:
IP是Internet Protocol的简称,是一种网络协议。Internet网络采用的协议是TCP/IP协议,其全称是Transmission Control Protocol/Internet Protocol。Internet依靠TCP/IP协议,在全球范围内实现了不同硬件结构、不同操作系统、不同网络系统间的互联。在Internet网络上存在着数以亿计的主机,每台主机都用网络为其分配的Internet地址代表自己,这个地址就是IP地址。IP地址用4个字节(16个字节),也就是32位(128位)的二进制数来表示,称为IPv4(ipv6)。为了便于使用,通常取用每个字节的十进制数,并且每个字节之间用圆点隔开来表示IP地址,如192.168.1.1。

注意:可以在Internet这种公网上使用的,必须是全球唯一的,不可重复,未连接到Internet上的私有网络可以使用这些地址 只要在这个私有网络里是唯一的有效地址就可以 但是不能连接到Internet上使用


端口:
一般而言,一台计算机只有单一的连到网络的物理连接(Physical Connection),所有的数据都通过此连接对内、对外送达特定的计算机,这就是端口。网络程序设计中的端口(port)并非真实的物理存在,而是一个假想的连接装置。端口被规定为一个在0~65535之间的整数。HTTP服务一般使用80端口,FTP服务使用21端口。假如一台计算机提供了HTTP、FTP等多种服务,那么客户机会通过不同的端口来确定连接到服务器的哪项服务上, 通常,0~1023之间的端口数用于一些知名的网络服务和应用,用户的普通网络应用程序应该使用1024以上的端口数,以避免端口号与另一个应用或系统服务所用端口冲突。
在这里插入图片描述
套接字(Socket):网络程序中的套接字(Socket)用于将应用程序与端口连接起来。套接字是一个假想的连接装置,就像插座一样可连接电器与电线.
在这里插入图片描述
如图,java将socket抽象化为类,我们只需要对类进行实例化,即可使用套接字;


1.tcp通信程序:tcp通信实现2台计算机的数据交互,通信的两端的主次之分,一个是服务器程序,另一个是客户机程序;
图片来自于网络
inetaddress类:
在这里插入图片描述

import java.net.InetAddress;
import  java.net.Socket;
import java.net.UnknownHostException;

public class client {
    
    
    public static void main(String[] args) throws UnknownHostException {
    
            
        InetAddress ip;
        //会在主机不存在或网络连接错误时抛出异常
        ip=InetAddress.getLocalHost();
        String localname=ip.getHostName();
        String localip=ip.getHostAddress();
        System.out.println(localname+" "+localip);
        InetAddress ip2=InetAddress.getByName("WIN-QG77E00RTV8");
        System.out.println(ip2.getHostAddress());
        
    }

}

运行结果
在这里插入图片描述
socket类:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import  java.net.Socket;
import java.net.UnknownHostException;
//客户端
public class client {
    
    
    public static void main(String[] args) throws IOException {
    
    
        InetAddress ip;
        ip=InetAddress.getLocalHost();
        //1.创建一个客户端对象socket,host代表服务器的ip,port代表端口
        Socket yf=new Socket(ip,8888);
        
        

        //2.通过socket创建outputstream对象
        OutputStream yfs=yf.getOutputStream();
        //3.使用write方法传输数据
        yfs.write("我喜欢你".getBytes());
        //4.接受服务器的信息
        InputStream yfsm=yf.getInputStream();
        byte []message=new byte [1024];
        int len=yfsm.read(message);
        System.out.println(new String(message,0,len ));
        yf.close();


    }

}

在这里插入图片描述
报错是因为根本没有服务器

注意:因为传送数据种类很多只能使用字节流

既然没客户端,我们就加呗;

serversocket类:
在这里插入图片描述
补充:serversocket也就是服务器套接字一次只可以与一个套接字连接,如果多台客户端同时提出连接请求,服务器套接字会将他们存入队列,如果请求连接数大于最大容量,请求会被直接拒绝;队列默认大小为50

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

//服务器
public class server {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //1.创建服务器serversocket对象
        ServerSocket yjl=new ServerSocket(8888);
        ServerSocket yjl1=new ServerSocket();//这是跟系统要指定的端口号,方面找到
        //系统随机分配端口号
        /*我们分析下它抛出异常的原因
          1.创建了非绑定服务器的套接字
          2.创建了绑定到特定客户端的端口的服务器套接字
          ....
          因为我们只说了2种构造方法
         */

        //2.通过accept接受正在请求的客户端socket
        Socket yjls=yjl.accept();
        //3.创建inputstream对象
        InputStream yjlss=yjls.getInputStream();
        byte []message=new byte[1024];
        //4.读取
        int len=yjlss.read(message);
        System.out.println(new String(message,0,len));
        //5.创建一个outputstream对象
        OutputStream yjlsm=yjls.getOutputStream();
        yjlsm.write("我也喜欢你".getBytes());

        yjl.close();
        yjl1.close();
        yjls.close();

    }
}

运行后
在这里插入图片描述
我们会看到多了个这个 状态是监听状态(腾讯网络管家 的网络连接功能可以查看)
在我们启动客户端前是这样的
在这里插入图片描述
启动后是这样的
在这里插入图片描述
在这里插入图片描述

udp程序设计基础:
udp传输数据是以包的形式;

datagrampacket类

public DatagramPacket(byte buf[], int length)
//指定了数据包的内存空间和大小
public DatagramPacket(byte buf[], int length,InetAddress address, int port) 
//指定了数据包的内存空间,大小,目标地址和端口
//在发送数据时,必须指定收方的socket 地址和端口,故使用第二种方法可创建发送数据的DatagramPacket对象

datagramsocket类

 public DatagramSocket() 
 //构造数据包套接字,并随机分配端口
 public DatagramSocket(int port) 
  //构造数据包套接字,并分配指定端口(符合之前说的规矩)
 public DatagramSocket(int port, InetAddress laddr)
 //构造数据包套接字,并分配指定端口,且绑定在指定的本地地址上,适用于多个网卡的设备

如果把datagrampacket比做货物,datagramsocket就是码头,无论发出数据还是接受数据都要通过它

实例:
客户端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;

//客户端
public class client {
    
    
    public static void main(String[] args) throws IOException {
    
    
        InetAddress ip;
        ip=InetAddress.getLocalHost();
        String sentence="我喜欢你";
        byte []yfdata=sentence.getBytes();
        //把货物拆了 方便运输
        DatagramPacket yf=new DatagramPacket(yfdata,yfdata.length,ip,8888);
        //准备一个集装箱(内容,大小,国家,具体那个码头)
        DatagramSocket sender=new DatagramSocket();
        //创建一个码头
        sender.send(yf);
        //发船
        sender.close();
        //下班







    }

}

服务器端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;

//服务器
public class server {
    
    
    public static void main(String[] args) throws IOException {
    
    
        InetAddress ip;
        ip=InetAddress.getLocalHost();
        DatagramSocket yjl=new DatagramSocket(8888);
        //因为服务器的ip是确定的,也就是国家是确定,我们则需要一个8888的码头
        byte []xx=new byte[1024];
        

        DatagramPacket yjlp=new DatagramPacket(xx,xx.length);
        //准备集装箱
        yjl.receive(yjlp);
        //码头收货
        xx=yjlp.getData();
        //把货物拿出来
        String yy=new String(xx,0,xx.length);
        //重新拼装
        System.out.println(yy);
        yjl.close();

    }
}

运行结果:
在这里插入图片描述
在这里插入图片描述
MulticastSocket类
可以理解为一个强大的码头,可以给多个ip地址的相同端口发送相同数据

 public void joinGroup(InetAddress mcastaddr)
 //将一个ip地址加入发送组
 public void leaveGroup(InetAddress mcastaddr)
 //将一个ip从发送组中删除

实例:因为整体思路差不多 我就不细说了
客户端

import java.io.*;
import java.net.*;
import java.util.*;
public class client
{
    
    
    public static void main(String[] args) throws IOException
    {
    
       
        MulticastSocket socket = new MulticastSocket(4446);
        
        InetAddress address = InetAddress.getByName("230.0.0.1");
        socket.joinGroup(address);
        DatagramPacket packet;
        //发送数据包
        byte[] buf = "Hello,This is a member of multicast!".getBytes();
        packet = new DatagramPacket(buf, buf.length,address,4445);
        socket.send(packet);
        //接收数据包并打印
        byte[] rev = new byte[512];
        packet = new DatagramPacket(rev, rev.length);
        socket.receive(packet);
        String received = new String(packet.getData()).trim();
        System.out.println("received: " + received);
        //退出组播组,关闭socket
        socket.leaveGroup(address);
        socket.close();
    }
}

服务器

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;

//服务器
public class server
{
    
    
    public static void main(String[] args) throws IOException
    {
    
    
        MulticastSocket socket = new MulticastSocket(4445);
        InetAddress address = InetAddress.getByName("230.0.0.1");
        socket.joinGroup(address);
        DatagramPacket packet;
        //接收数据包
        byte[] buf = new byte[512];
        packet = new DatagramPacket(buf, buf.length);
        socket.receive(packet);
        //打印数据包
        String received = new String(packet.getData()).trim();
        System.out.println("received: " + received);
        //发送数据包
        byte[] sen=received.getBytes();
        packet=new DatagramPacket(sen,sen.length,address,4446);
        socket.send(packet);
        //退出组播组,关闭socket
        socket.leaveGroup(address);
        socket.close();
    }
}

我上面介绍的类都说的很浅,因为如果对每个类都进行细说篇幅会有点大,所以我只介绍了一些基本操作但我相信你们大致学懂了,只剩下这些类更高级的使用,如今有了一定的框架大家可以在网上找专门讲解这些类的博客进行学习

如有错误,敬请指出,如果满意还请点个赞哦

猜你喜欢

转载自blog.csdn.net/jahup/article/details/106148785