java网络编程
来源:互联网 发布:富春山居图有多烂 知乎 编辑:程序博客网 时间:2024/06/05 14:46
一.网络基础知识
1.OSI(Open System Interconnection)七层模型和TCP/IP协议
2.七层模型与协议之间的对应关系
3.网络编程三要素:
1)IP地址:每台电脑都有唯一的标识:ip
常用的IP A类:1网络+3主机 可连接主机个数 2563 通常大学里面或一些政府部门(1-127)
B类:2网络+2主机 可连接主机个数 2562 (128-191)
C类:3网络+1主机 可连接主机个数 256(192-223)
127.0.0.1:回环地址(也可以表示本机地址)
xxx.xxx.xxx.255广播地址
ping ip地址:查看当前本机与这台PC机器的网络通信
2)端口:两台PC通信,除了知道IP地址,还要知道端口号
有效端口号:0-65535
保留端口好:0-1024
3)协议:TCP协议和UDP协议区别:
TCP(传输控制协议):
建立连接通道(通道内的流使用的是最基本的字节流)
可靠协议
服务器要等待客户端连接,执行效率低
使用TCP协议可以发送大量的数据,文件大小无限制
UDP(用户数据报协议):
无需建立连接通道(数据包的形式)
不可靠协议
执行效率高
UDP发送数据有限制
4.如果一个类没有构造方法(三种情况)
1)这个类里面的成员方法都是静态(Math、Arrays、Collections)
2)单例模式:在内存始终只有一个对象,将构造方法私有化,在成员变量创建该类的实例(并且该实例被static修饰)提供该类公共方法可以通过外界调用
3)该类中会有某些静态成员方法的返回值是该类本身(InetAddress类:表示互联网协议(IP)地址)
5.InetAddress类:表示互联网协议(IP)地址
常用方法:
1)String getHostAddress()
返回 IP 地址字符串(以文本表现形式)
2)byte[]
getAddress()返回此
InetAddress
对象的原始 IP 地址
6.Socket编程
包括两种:TCP和UDP编程,两端必须有socket对象,还必须有IP地址和端口号
二.UDP编程
发送端(Send):
1.创建UDP协议发送端的Socket对象(DatagramSocket()):用来发送和接收数据包的套接字
2.创建数据包(通过这个数据包将数据发送到接收端):public DatagramPacket(byte[] buf, int length ,InetAddress address,int port)
3.调用UDP协议发送端发送的方法
4.关闭资源
接收端(Receive):
1.创建接收端的Socket对象(DatagramSocket())
2.创建一个数据包接收发送端发来的数据包
3.接收数据,调用DateSocket类中的接收方法:阻塞式,等待发送端发送数据,没有数据就一直等待
4.解析数据包里面的实际数据,显示在控制台上
5.关闭资源
package udp2;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;//import java.net.SocketException;//import java.net.UnknownHostException;/**发送端: * 1.创建UDP协议发送端的socket对象(DatagramSocket()) * 2.创建数据包:通过数据包将数据发送到接收端:public DatagramPacket(byte[] buf,int length,InetAddress address,int port) * 3.调用UDP协议发送方法 * 4.关闭资源 */public class SendDemo {public static void main(String[] args) throws Exception {//1.创建UDP协议发送端的socket对象(DatagramSocket())DatagramSocket ds = new DatagramSocket();//2.创建数据包public DatagramPacket(byte[] buf,int length,InetAddress address,int port)byte[] bys = "hello udp".getBytes();DatagramPacket dp = new DatagramPacket(bys,bys.length,InetAddress.getByName("192.168.1.131"),666);//3.调用UDP协议发送方法ds.send(dp);//4.关闭资源ds.close();}}
package udp2;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;//import java.net.SocketException;/**接收端: * 1.创建接收端的Socket对象 * 2.创建一个数据包接收发送端发来的数据报包(接收容器) * 3.接收数据,调用DateSocket类中的接收方法来接收数据包 * 4.解析数据包里面的实际数据,显示在控制台上 * 5.关闭资源 */public class ReceiveDemo {public static void main(String[] args) throws IOException {//1.创建接收端的Socket对象DatagramSocket ds = new DatagramSocket(666);//2.创建一个数据包接收发送端发来的数据报包(接收容器)byte[] bys = new byte[1024];DatagramPacket dp = new DatagramPacket(bys,bys.length);//3.接收数据ds.receive(dp);//4.解析数据并显示在控制台上String ip = dp.getAddress().getHostAddress();//获取缓冲区中的实际数据byte[] dataBys = dp.getData();//获取实际缓冲区的数据的长度int len = dp.getLength();String s = new String(dataBys,0,len);//输出到控制台System.out.println(ip+"传输的数据是:"+s);//关闭资源ds.close();}}键盘录入的两种方式:
1.Scanner类
2.BufferedReader类(字符缓冲流)特有功能 readLine():一次读取一行
BufferedReader br = new BufferedReader(new InputStreamReader(system.in));
对以上的发送端进行优化,发送端的数据来源是不停的键盘录入
package udp3;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;//import java.net.SocketException;public class SendDemo {public static void main(String[] args) throws IOException {//1.创建UDP协议发送端的socket对象(DatagramSocket())DatagramSocket ds = new DatagramSocket();//2.创建数据包public DatagramPacket(byte[] buf,int length,InetAddress address,int port//字符缓冲流BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//一次读取一行String line = "null";while((line=br.readLine())!=null){//发送端不停发送的结束条件if("886".equals(line)){break;}//创建数据包byte[] bys = line.getBytes();DatagramPacket dp = new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.1.131"),888);//3.调用UDP协议发送方法ds.send(dp);}//4.释放资源ds.close();}}
package udp3;//import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;//import java.net.InetAddress;import java.net.SocketException;public class ReceiveDemo {public static void main(String[] args) throws SocketException,Exception {// 1.创建接收端的Socket对象DatagramSocket ds = new DatagramSocket(888);while(true){//2.创建接收容器//创建字符缓冲区byte[] bys = new byte[1024];DatagramPacket dp = new DatagramPacket(bys, bys.length);//3.接收数据ds.receive(dp);//4.解析数据//获取发送端的IP地址String ip = dp.getAddress().getHostAddress();//获取实际缓冲区的数据byte[] dataBys = dp.getData();//实际缓冲区的长度int len = dp.getLength();String s = new String(dataBys, 0, len);//显示到控制台上System.out.println(ip+"发送了数据:"+s);//5.释放资源:由于模范一直发送的数据,所以不用释放//ds.close();}}}接收端和发送端是在两个窗口中显示的,如何让这两个接收端和发送端处于一个窗口下(main中)
package udprunnable;import java.net.DatagramSocket;import java.net.SocketException;public class ChatRoom {/** * 需求:接收端和发送端是在两个窗口中显示的,如何让这两个接收端和发送端处于一个窗口下(main中) * (使用多线程第二种方式:Runable接口的方式实现 发送端和接收端处于一个主线程中) */public static void main(String[] args) {//创建发送端和接收端的Socket对象try {DatagramSocket sendSocket = new DatagramSocket();DatagramSocket receiveSocket = new DatagramSocket(888);//创建资源对象SendThread st = new SendThread(sendSocket);ReceiveThread rt = new ReceiveThread(receiveSocket);//创建线程类对象Thread t1 = new Thread(st);Thread t2 = new Thread(rt);//启动线程t1.start();t2.start();} catch (SocketException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
package udprunnable;import java.io.BufferedReader;//import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;//import java.net.UnknownHostException;public class SendThread implements Runnable{private DatagramSocket ds;public SendThread(DatagramSocket ds) {super();this.ds = ds;}@Overridepublic void run() {try {//创建发送端Socket对象BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//一行读取一个数据String line = null;while((line=br.readLine())!=null){//结束条件if("886".equals(line)){break;}//创建数据包byte[] bys = line.getBytes();DatagramPacket dp = new DatagramPacket(bys,bys.length,InetAddress.getByName("192.168.1.131"),888);//发送数据ds.send(dp);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{//释放资源if(ds!=null){ds.close();}}}}
package udprunnable;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;public class ReceiveThread implements Runnable{private DatagramSocket ds;public ReceiveThread(DatagramSocket ds) {super();this.ds = ds;}@Overridepublic void run() {try {while(true){//创建接收容器byte[] bys = new byte[1024];DatagramPacket dp = new DatagramPacket(bys, bys.length);//接收数据ds.receive(dp);//解析数据String ip = dp.getAddress().getHostAddress();//获取实际缓冲区的数据byte[] dateBys = dp.getData();//实际实际缓冲区数据的长度int len = dp.getLength();String s = new String(dateBys,0,len);System.out.println(ip+"发送的数据是"+s);}//接收要不停接收数据,不需要关闭} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}三.TCP编程
客户端步骤:
1.创建客户端的Socket对象(Socket)
2.获取通道内的流(输出流)
3.使用输出流写数据
4.关闭客户端的Socket对象
服务器端步骤:
1.创建服务器端的Socket对象(ServerSocket)
2.服务器端需要监听客户端的连接
public Socket accept() throws IOException
3.获取通道内的输入流
4.将客户端发送的数据显示在控制台上
package tcp;import java.io.IOException;//import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;public class ClientDemo {/**客户端 * 1.创建客户端的Socket对象 * 2.获取通道内的输出流 * 3.使用输出流写数据 * 4.关闭客户端的流 * @throws IOException * @throws UnknownHostException * * */public static void main(String[] args) throws UnknownHostException, IOException {//1.创建客户端的Socket对象Socket s = new Socket("192.168.10.136",8888);//2.获取通道内的输出流OutputStream out = s.getOutputStream();//3.使用输出流写数据out.write("hello TCP".getBytes());//4.关闭客户端的流s.close();}}
package tcp;import java.io.IOException;import java.io.InputStream;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {/**服务器端: * 1.创建服务器端的socket对象 * 2.监听服务器端的连接 * 3.获取通道内的输入流 * 4.将客户端的数据显示在控制台上 * @param args * @throws IOException */public static void main(String[] args) throws IOException {// 1.创建服务器端的socket对象ServerSocket ss = new ServerSocket(8888); //2.监听服务器端的连接Socket s = ss.accept();//3.获取通道内的输入流InputStream in = s.getInputStream();//4.将客户端的数据显示在控制台上byte[] bys = new byte[1024];int len = in.read(bys);String str = new String (bys,0,len);//获取主机的IP地址InetAddress address = s.getInetAddress();String ip = address.getHostAddress();System.out.println(ip+"发送的数据是:"+str);//关闭服务器s.close();//关闭掉侦听的客户端所在的通道内的对象(Socket)ss.close();}}改进版1:互相加入反馈
package tcp2;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;public class CilentDemo {/** * @param args * @throws IOException * @throws UnknownHostException */public static void main(String[] args) throws UnknownHostException, IOException {//1.创建客户端的Socket对象Socket s = new Socket("192.168.1.131",888);//2.获取通道内的输出流OutputStream out = s.getOutputStream();//3.使用输出流写数据out.write("hello TCP".getBytes());//获取到服务器反馈的数据//获取通道内的输入流数据InputStream in = s.getInputStream();byte[] bys = new byte[1024];int len = in.read(bys);//读取服务器端发送来的实际字节数(阻塞式)//显示服务器端反馈的数据String client = new String(bys,0,len);System.out.println("client:"+client);//4.关闭客户端的流s.close();}}
package tcp2;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {/** * @param args * @throws IOException */public static void main(String[] args) throws IOException {// 1.创建服务器端的socket对象ServerSocket ss = new ServerSocket(888); System.out.println("正在等待客户端连接...");//2.监听服务器端的连接Socket s = ss.accept();//阻塞式方法结束System.out.println("该客户端已连接...");//3.获取通道内的输入流InputStream in = s.getInputStream();//4.将客户端的数据显示在控制台上byte[] bys = new byte[1024];int len = in.read(bys);String server = new String (bys,0,len);//输出客户端发送的数据System.out.println("server"+server);//服务器反馈//获取通道内的输出流OutputStream out = s.getOutputStream();out.write("已收到来自客户端的消息".getBytes());//关闭资源s.close();//关闭掉侦听的客户端所在的通道内的对象(Socket)ss.close();}}改进版2:客户端键盘录入数据,服务器端将数据显示在控制台上
注意通道内的流是字节流,所以要封通道内的流
package tcp3;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.Socket;import java.net.UnknownHostException;public class ClientDemo {/** * 客户端键盘录入消息 * @param args * @throws IOException * @throws UnknownHostException */public static void main(String[] args) throws IOException {//创建客户端的Socket对象Socket s = new Socket("192.168.1.131",888);//键盘录入数据(IO流的形式)//字符流封装数据BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//String str = br.readLine();//封装通道内的流(要发送的数据)BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//一次读取一行数据String line = null;while((line=br.readLine())!=null){//键盘录入一行数据,就把一行数据封装到通道内的流中//自定义结束条件if("over".equals(line)){break;}bw.write(line);bw.newLine();bw.flush();}//关闭资源s.close();}}
package tcp3;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {/** * @param args * @throws IOException */public static void main(String[] args) throws IOException {// 1.创建服务器端的socket对象ServerSocket ss = new ServerSocket(888); System.out.println("正在等待客户端连接...");//2.监听服务器端的连接Socket s = ss.accept();//阻塞式方法结束System.out.println("该客户端已连接...");//3.封装服务器通道内的流BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//一次读取一行数据String line = null;while((line=br.readLine())!=null){//输出数据System.out.println(line);}s.close();ss.close();}}改进版3 客户端键盘录入,服务器端输出一个文件
客户端同版本2,以下是服务器端
package tcp4;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {/** * @param args * @throws IOException */public static void main(String[] args) throws IOException {// 1.创建服务器端的socket对象ServerSocket ss = new ServerSocket(888); System.out.println("正在等待客户端连接...");//2.监听服务器端的连接Socket s = ss.accept();//阻塞式方法结束System.out.println("该客户端已连接...");//3.封装服务器通道内的流BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//4.服务器端输出一个文本文件BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));//服务器端通道内的流读取客户端的发送数据String line = null;while((line=br.readLine())!=null){//写入到文本中bw.write(line);bw.newLine();bw.flush();}s.close();bw.close();ss.close();}}改进版4 客户端文本文件,服务器端显示在控制台上
服务器端同版本2,以下是客户端
package tcp5;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.IOException;import java.io.OutputStreamWriter;import java.net.Socket;import java.net.UnknownHostException;public class ClientDemo {/** * 客户端录入文本文件 * @param args * @throws IOException * @throws UnknownHostException */public static void main(String[] args) throws IOException {//创建客户端的Socket对象Socket s = new Socket("192.168.1.131",888);//读取文本文件的内容//字符流封装数据BufferedReader br = new BufferedReader(new FileReader("a.txt"));//String str = br.readLine();//封装通道内的流(要发送的数据)BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//一次读取一行数据String line = null;while((line=br.readLine())!=null){//键盘录入一行数据,就把一行数据封装到通道内的流中bw.write(line);bw.newLine();bw.flush();}//关闭资源br.close();s.close();}}改进版5 客户端是文本文件,服务器端将文本文件的内容复制到一个新的文本文件中
客户端同版本4,服务器端如下:
package tcp6;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {/** * @param args * @throws IOException */public static void main(String[] args) throws IOException {// 1.创建服务器端的socket对象ServerSocket ss = new ServerSocket(888); System.out.println("正在等待客户端连接...");//2.监听服务器端的连接Socket s = ss.accept();//阻塞式方法结束System.out.println("该客户端已连接...");//3.封装服务器通道内的流BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//将通道流中的数据写到文本文件中BufferedWriter bw = new BufferedWriter(new FileWriter("newB.txt"));//一次读取一行数据String line = null;while((line=br.readLine())!=null){//输出数据bw.write(line);bw.newLine();bw.flush();}//关闭资源s.close();bw.close();ss.close();}}改进版本6 客户端是图片文件,服务器端输出一个图片文件,并且给出反馈
图片:以字节缓冲流的方式读写(BufferedInputStream、BufferedOutputStream)
package tcpimg;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.net.Socket;/** *客户端的图片文件,服务器端输出一个图片文件并且给出反馈 *2017年12月13日 */public class ClientDemo {public static void main(String[] args) throws IOException {// 创建客户端Socket对象Socket s = new Socket("192.168.1.131",888);//先封装文件BufferedInputStream bis = new BufferedInputStream(new FileInputStream("山里.jpg")) ;//获取通道内的流BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());//读取图片信息,一次读取一个字节数组byte[] bys = new byte[1024];int len = 0;while((len = bis.read(bys))!=-1){//读取字节到输出流中bos.write(bys,0,len);bos.flush();}//客户端需要给服务器提供一个终止,告诉服务器端我没有数据了s.shutdownOutput();//客户端读取服务器端的反馈InputStream is = s.getInputStream();byte[] bys2 = new byte[1024];int len2 = is.read(bys2);System.out.println(new String(bys2,0,len2));//关闭资源bis.close();s.close();}}
package tcpimg;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {public static void main(String[] args) throws IOException {//创建服务器端Socket对象ServerSocket ss = new ServerSocket(888); //监听客户端连接Socket s = ss.accept();//封装通道内的流BufferedInputStream bis = new BufferedInputStream(s.getInputStream());//输出图片文件BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("山理.jpg"));//一次读取一个字节数组byte[] bys = new byte[1024];int len = 0;while((len=bis.read(bys))!=-1){bos.write(bys, 0, len);bos.flush();}//服务器端给客户端反馈OutputStream out = s.getOutputStream();out.write("文件上传成功".getBytes());//释放资源bos.close();s.close();ss.close();}}
- 【网络编程】JAVA网络编程
- java网络编程:网络基本概念
- Java网络编程-UDP编程
- Java 高层网络编程
- Java网络编程2
- Java网络编程3
- Java网络编程4
- Java网络服务器编程
- java网络编程1
- java网络编程2
- JAVA网络编程
- Java网络服务器编程
- java网络编程
- Java 高层网络编程
- Java 高层网络编程
- Java网络服务器编程
- Java网络编程
- JAVA网络编程
- Mybatis连接mysql数据库时中文乱码问题
- 《数字技术》连载10: 第2章 数字器件 第5节 TTL 门电路
- 算法基础【2】OJ网站整理
- 网络工程师必看 OSI七层模型协议
- python+multiprocess+theano+pylucene--内存泄露解决方案
- java网络编程
- GPIO中断处理函数
- 使用jackson进行字符串,集合和json之间的转换
- 海思开发板上添加ftp功能
- AnglurJS 常用过滤器
- 通过案例学调优之--Oracle Time Model(时间模型)
- 手把手| 用Python代码建个数据实验室,顺利入坑比特币
- struts2-9为应用指定多个配置文件
- 蓝桥杯 ADV-188 算法提高 排列数(java) 深度优先搜索 DFS