栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java网络编程基础

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java网络编程基础

网络编程

一、网络的相关概念

1.网络通信2.网络3 .IP地址4.ipv4地址分类5.域名和端口号6.网络通信协议7. TCP和UDP 二、InetAddress 类

1.相关方法2.实例操作 三、Socket

1.TCP网络通信编程

1.1基本介绍1.2案例1:客户端发送信息给服务端1.3案例2:客户端发信息给服务器端,并接收服务器端发回来的消息1.4案例3:使用字符流1.5案例4:发送图片1.6netstat指令1.7 TCP 网络通讯不为人知的秘密 2.UDP网络编程(了解)

1. 基本介绍2.基本流程3.案例

本文的图片大部分引用于韩顺平老师,对网络编程基础做了总结,至于更详细的内容,大家可以去看计算机网络

一、网络的相关概念 1.网络通信

2.网络


网络编程的目的:直接或间接地通过网络协议与其他计算机实现数据交换进行通讯
要想实现网络编程,需要关注两个问题:
1.如何准确定位网络上的一台或多台主机,定位主机上的特定应用
2.找到主机以后怎么进行可靠高效的数据传输

3 .IP地址


IP地址就是网络上定位的一台主机,端口号就是定位这台主机是哪一个应用在进行通信,端口号用来区分一台主机上面的不同应用程序

4.ipv4地址分类


5.域名和端口号

比如说我们想要访问一个网站,由于IP地址难以记忆,我们一般在浏览器上写的是域名,域名经过DNS域名解析服务器,会把域名解析出来,看它的IP是多少,解析完以后,再拿这个IP地址去访问对应的服务器,就可以把这个资源访问到了

不同的进程对应不同的端口号
端口号与IP地址的组合得出一个网络套接字:Socket

一个服务要接收和发送数据的话,需要有一个端口。端口就类似于人的耳朵,我们要听懂别人的话,必须要有耳朵

6.网络通信协议


OSI模型过于理想化,没有被广泛推广

7. TCP和UDP


TCP类似于打电话
UDP类似于发短信
TCP三次握手
举一个生活中的小例子:打电话
打电话的时候,假设一个叫tom,一个叫kim,tom想要打电话和kim说事情,这个时候,电话必须打通,才可以传递信息,就类似于TCP连接。为了确保kim有在听,tom在传递信息之前先问一句,你在听吗?kim听到后就回说在听,然后tom就说我要开始说事情了,紧接着开始说事情

UDP协议无法保证传输的数据一定被接收到
UDP协议就是没有确认对方是否能够接收到消息,就直接传输信息
比如说:你发送信息给别人,但是这个电话号码可能停机了或者说注销了,你不能确保别人能接收消息,类似于UDP协议

假如说现在有一个人也想要打电话给kim,由于kim这个时候在和tom打电话,他们两个如果电话没有挂掉,这个人的电话是打不通的,就类似于TCP协议要释放已经建立的连接

tom发信息给kim,另外一个人同样也可以发信息给kim,就类似于UDP协议不需要释放资源

二、InetAddress 类

一个InetAddress类的对象就当于是一个IP地址

//File file=new File(“hello.txt”);
//比如说在这里file就对应内存中的hello.txt这个文件
//类似于这个
//inet1就对应一个具体的IP地址
InetAddress inet1=InetAddress.getByName(“192.168.10.14”);
//写上主机名就可以返回对应的对象

1.相关方法

getByName(String host) 、 getLocalHost()
两个常用方法:getHostName() 获取域名 / getHostAddress() 获取主机地址

2.实例操作

package com.zyh.java;

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


public class InetAddressMethod {
    public static void main(String[] args) throws UnknownHostException {
  //获取本机的InetAddress对象
        InetAddress localHost = InetAddress.getLocalHost();
        
        //计算机名称和识别到的ip地址
        System.out.println(localHost);

        //我们也可以根据主机名来获取InetAddress对象
        InetAddress byName = InetAddress.getByName("这里写上你的主机名");
        System.out.println("host="+byName);

        //根据域名来返回InetAddress对象
        InetAddress byName1 = InetAddress.getByName("www.baidu.com");
        System.out.println("百度:"+byName1);

        //根据InetAddress对象获取对呀的主机地址
        String hostAddress = byName1.getHostAddress();
        System.out.println(hostAddress);//ip地址

        //通过InetAddress对象,获取对应的主机名或者域名
        String hostName = byName1.getHostName();
        System.out.println(hostName);

    }
}

三、Socket

Socket就类似于通信的通道,发送数据是通过socket

两台主机要通信首先要建立连接,就相当于是建立一个数据通道

客户端发起连接,服务器端接收连接就会形成这样一个数据通道

Socket有两个编程方式:TCP编程和UDP编程

1.TCP网络通信编程 1.1基本介绍


Socket最后记得关闭,不然连接越来越多,最后就导致无法连接

1.2案例1:客户端发送信息给服务端


思路:

ServerSocket可以有多个Socket,也就是说服务器端可以和多个客户端连接,否则就不能处理多并发问题

服务器端:

package com.zyh.java;

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


public class SocketTCP01Server {
    public static void main(String[] args) throws IOException {
        //在本机的9999端口监听,等待连接
        //要求:本机没有其他服务监听这个端口
        //ServerSocket可以有多个Socket 通过accept可以返回多个Socket
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务器端在9999端口等待连接...");
        //如果没有客户端连接此端口,程序就会阻塞,等待连接
        //如果有客户端连接,则返回Socket对象
        Socket socket = serverSocket.accept();
        //没有连接的话,下面的代码都不会运行

        System.out.println("服务器端 socket="+socket.getClass());

        System.out.println("服务器端开始接收信息");
        //连接以后要读取客户端发送的信息
        //通过IO读取
        InputStream inputStream = socket.getInputStream();
        byte[] bytes=new byte[10];
        int len;
        while ((len=inputStream.read(bytes))!=-1){
            String s = new String(bytes, 0, len);
            System.out.print (s);
        }
        //关闭流和socket
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

客户端:

package com.zyh.java;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;


public class SocketTCP01Client {
    public static void main(String[] args) throws IOException {
    //连接服务器端 (ip,端口)
        //连接某一台主机的9999端口,如果连接成功,返回socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客户端 socket返回="+socket.getClass());

        //连接上后,生成Socket,发送数据给服务端,通过socket,getOutputStream()
        //得到和socket对象关联的输出流对象
        System.out.println("客户端要开始发消息给服务端了");
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,server".getBytes());

        //关闭流对象和socket
        outputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }
}

运行效果:

在服务器端:

服务器端在9999端口等待连接...
服务器端 socket=class java.net.Socket
hello,server

在客户端:

客户端 socket返回=class java.net.Socket
客户端退出
1.3案例2:客户端发信息给服务器端,并接收服务器端发回来的消息


注意:服务器端发消息给客户端的时候,客户端并不知道服务器端什么时候发送信息结束,也就是发送信息的时候,要有一个结束标记,不然就会一直等待,同样的,另外一个发送信息的时候,发送结束也应该要有一个结束标记,不然就不知道对方还要不要继续发送信息

服务器端:

package com.zyh.java;

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


public class SocketTCP02Server {
    public static void main(String[] args) throws IOException {
        //在本机的9999端口监听,等待连接
        //要求:本机没有其他服务监听这个端口
        //ServerSocket可以有多个Socket 通过accept可以返回多个Socket
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务器端在9999端口等待连接...");
        //如果没有客户端连接此端口,程序就会阻塞,等待连接
        //如果有客户端连接,则返回Socket对象
        Socket socket = serverSocket.accept();
        //没有连接的话,下面的代码都不会运行

        System.out.println("服务器端 socket="+socket.getClass());

        System.out.println("服务器端开始接收信息");
        //连接以后要读取客户端发送的信息
        //通过IO读取
        InputStream inputStream = socket.getInputStream();
        byte[] bytes=new byte[10];
        int len;
        while ((len=inputStream.read(bytes))!=-1){
            String s = new String(bytes, 0, len);
            System.out.print (s);
        }
        //获取 socket 相关联的输出流
	OutputStream outputStream = socket.getOutputStream();
	outputStream.write("hello, client".getBytes());
//      设置结束标记
	socket.shutdownOutput();
        //关闭流和socket
        outputStream.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

客户端:

package com.zyh.java;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;


public class SocketTCP02Client {
    public static void main(String[] args) throws IOException {
    //连接服务器端 (ip,端口)
        //连接某一台主机的9999端口,如果连接成功,返回socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客户端 socket返回="+socket.getClass());

        //连接上后,生成Socket,发送数据给服务端,通过socket,getOutputStream()
        //得到和socket对象关联的输出流对象
        System.out.println("客户端要开始发消息给服务端了");
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,server".getBytes());
        //      设置结束标记
socket.shutdownOutput();

//  获取和 socket 关联的输入流.  读取数据(字节) ,并显示
	InputStream inputStream = socket.getInputStream();
	byte[] buf = new byte[1024];
	int readLen = 0;
	while ((readLen = inputStream.read(buf)) != - 1) {
			System.out.println(new String(buf, 0, readLen));
	}

        //关闭流对象和socket
        inputStream.close();
        outputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }
}

运行效果:

在服务器端:
```xml
服务器端在9999端口等待连接...
服务器端 socket=class java.net.Socket
hello,server

在客户端:

客户端 socket返回=class java.net.Socket
hello,client
客户端退出
1.4案例3:使用字符流


客户端

package com.hspedu.socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

 
@SuppressWarnings({"all"})
public class SocketTCP03Server {
public static void main(String[] args) throws IOException {
//思路
//1.  在本机 的 9999 端口监听,  等待连接
//      细节:  要求在本机没有其它服务在监听 9999

//      细节: 这个 ServerSocket  可以通过 accept()  返回多个 Socket[多个客户端连接服务器的并发] ServerSocket serverSocket = new ServerSocket(9999);
	System.out.println("服务端,在 9999 端口监听,等待连接..");
//2.  当没有客户端连接 9999 端口时,程序会 阻塞,  等待连接
//      如果有客户端连接,则会返回 Socket 对象,程序继续
	Socket socket = serverSocket.accept();

	System.out.println("服务端 socket =" + socket.getClass());
//
//3.  通过 socket.getInputStream()  读取客户端写入到数据通道的数据,  显示
	InputStream inputStream = socket.getInputStream();
//4. IO 读取,  使用字符流,  使用 InputStreamReader  将 inputStream  转成字符流     
	BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 
	String s = bufferedReader.readLine();
	System.out.println(s);//输出

//5.  获取 socket 相关联的输出流
	OutputStream outputStream = socket.getOutputStream();
//        使用字符输出流的方式回复信息
	BufferedWriter bufferedWriter = new BufferedWriter(new 	OutputStreamWriter(outputStream)); 
	bufferedWriter.write("hello client  字符流");
	bufferedWriter.newline();//  插入一个换行符,表示回复内容的结束
	bufferedWriter.flush();//注意需要手动的 flush

	//6.关闭流和 socket
	bufferedWriter.close();
	bufferedReader.close();
	socket.close();
	serverSocket.close();//关闭	

}
}	

服务端:

package com.hspedu.socket;	
import java.io.*;
import java.net.InetAddress; import java.net.Socket;	
 


@SuppressWarnings({"all"})
public class SocketTCP03Client {
public static void main(String[] args) throws IOException {
//思路
//1.  连接服务端 (ip ,  端口)
//解读:  连接本机的 9999 端口,  如果连接成功,返回 Socket 对象
	Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
	System.out.println("客户端 socket 返回=" + socket.getClass());
//2.  连接上后,生成 Socket,  通过 socket.getOutputStream()
//      得到 和 socket 对象关联的输出流对象
	OutputStream outputStream = socket.getOutputStream();
//3.  通过输出流,写入数据到 数据通道,  使用字符流
	BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); 
	bufferedWriter.write("hello, server  字符流");
	bufferedWriter.newline();
	//插入一个换行符,表示写入的内容结束,  注意,要求对方使用 readLine()
	//!!!! bufferedWriter.flush();
	//  如果使用的字符流,需要手动刷新,否则数据不会写入数据通道



//4.  获取和 socket 关联的输入流.  读取数据(字符) ,并显示
	InputStream inputStream = socket.getInputStream();
	BufferedReader bufferedReader = new BufferedReader(new 	InputStreamReader(inputStream)); String s = bufferedReader.readLine();
	System.out.println(s);

//5.  关闭流对象和 socket,  必须关闭
	bufferedReader.close();//关闭外层流
	bufferedWriter.close();
	socket.close();
	System.out.println("客户端退出.....");
}
}

运行结果:

1.5案例4:发送图片


1.6netstat指令


netstat - anb表示我们在查看程序的时候,知道是哪一个程序在占用这个端口

1.7 TCP 网络通讯不为人知的秘密


当客户端和服务器连接成功以后,客户端这里也有一个端口,它的端口是不确定的,是由TCP/IP分配的。客户端这里对应的端口和服务器端通讯

当传输结束以后,客户端的端口就被释放了

2.UDP网络编程(了解)

用得相对比较少,但是效率比较高

1. 基本介绍


2.基本流程


3.案例


package com.zyh.java.udptest;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;


public class SocketUDP01Reciver {
    public static void main(String[] args) throws IOException {
        //创建一个DatagramSocket对象,准备在9999端口接收数据
        DatagramSocket datagramSocket=new DatagramSocket(9999);
        //创建 DatagramPacket对象,准备接收数据
        //UDP数据包每一个大小被限制在64K内,不适合传输大量数据
        byte[] bytes=new byte[1024];
        DatagramPacket datagramPacket=new DatagramPacket(bytes,bytes.length);

        //调用接收方法,把通过网络传输的DatagramPacket对象
        //填充到packet对象
        //会在9999端口等待,如果有数据包发送到此端口,就会接收到数据
        //如果没有数据包发送到9999端口,就会阻塞,一直等,直到有数据传输
        System.out.println("接收端A等待接收数据...");
        datagramSocket.receive(datagramPacket);

        //把datagramPacket进行拆包,取出数据,并显示
        //因为数据的传输被包装起来了
        //返回实际接收的长度
        int length = datagramPacket.getLength();
        //接收到的数据
        byte[] data = datagramPacket.getData();
        String s = new String(data, 0, length);
        System.out.println(s);
        //关闭资源
        datagramSocket.close();
        System.out.println("A端退出");
    }
}

package com.zyh.java.udptest;

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


public class SocketUDP01Send {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket对象,准备发送和接收数据
        //准备在9998端口接收数据
        DatagramSocket socket=new DatagramSocket(9998);

        //把要发送的数据封装到DatagramPacket对象 内容字节数组,长度,主机(IP),端口
        byte[] buff= "hello,明天吃火锅".getBytes();
        //ipconfig可以查看网络配置
        DatagramPacket packet=new DatagramPacket(buff,buff.length,InetAddress.getLocalHost(),9999);

        //发送数据
        socket.send(packet);
        //关闭资源
        socket.close();
        System.out.println("B端退出");



    }
}

运行结果

接收端A等待接收数据...
hello,明天吃火锅
A端退出
B端退出```
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/750614.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号