黑马程序员——java基础-网络编程

------- android培训、java培训、期待与您交流! ----------

第一节:网络编程的概述
一、网路编程的简述:
1、计算机网络:
是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,
网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
2、网络编程:
就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。
3、网络编程模型图


4、网络编程的三要素
(1)、IP地址
(1).1 网络中设备的标识 
             (1).2 不易记忆,可用主机名 
             (1).3 本地回环地址:127.0.0.1 主机名:localhost 
(1).4 如何获取和操作IP地址呢?
(1).4.1 java提供了一个类InetAddress 供我们使用。
(1).4.2 InetAddress 无构造函数 可以通过getLocalHost()方法获取InetAddress对象(InetAddress ia=InetAddress.getLocalHost())。
(1).4.3 InetAddress类常用方法
        (1).4.3.1 static InetAddress getByName(String host) 得到指定主机的IP和主机名。
        (1).4.3.2 String getHostName() 得到IP地址主机名。
        (1).4.3.3 String getHostAddress()得到IP地址字符串文本形式,以IP地址为主。
(2)、端口
(2).1 每个网络程序都会至少有一个逻辑端口
(2).2用于标识进程的逻辑地址,不同进程的标识 
(2).3 有效端口,范围:0-65535。其中0-1024系统使用或保留端口。
(3)、传输协议:
(3).1 用进行数据传输的规则 ,常见有两种 TCP  UDP;
(3).2 UDP:将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快。
(3).3 TCP:建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低。
第二节:传输协议
一、Socket套接字:
     1、网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
     2、Socket原理机制:
           (1)、通信的两端都有Socket。
           (2)、网络通信其实就是Socket间的通信。
           (3)、数据在两个Socket间通过IO传输。
二、UDP传输协议
1、udp传输涉及的两个对象。
(1)、DatagramSocket:udp socket端点。  即可以发送,又可以接收。
DatagramSocket类常用方法:
(1).1 创建 UDP的Socket服务对象:
DatagramSocket(),不指定端口。DatagramSocket(int port),指定端口。
(1).2 void send(DatagramPacket p) 发送。
(1).3 void receive(DatagramPacket p) 接收。
(2)、DatagramPacket:数据包对象。
2、UDP协议发送和接收数据
 (1)、创建UDP传输的发送端。  
思路: 
(1).1、建立udp的socket服务。 
(1).2、将要发送的数据封装到数据包中。  
(1).3、通过udp的socket服务将数据包发送出去。 
(1).4、关闭socket服务。 
(1).5、代码体现

//UDP的发送端
import java.net.*;
class Demo
{
	public static void main(String[] args)throws Exception
	{
	
	DatagramSocket ds=new DatagramSocket();
	String str="我来了";
	byte[] buf=str.getBytes();
	DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.108"),10000);
	ds.send(dp);
	ds.close();

	
	}
}
(2)、建立UDP接收端。 
思路:
         (2).1、建立udp socket服务,因为是要接收数据,必须要明确一个端口号。 
(2).2、创建数据包,用于存储接收到的数据。方便用数据包对象的方法解析这些数据。
         (2).3、使用socket服务的receive方法将接收的数据存储到数据包中。 
         (2).4、通过数据包的方法解析数据包中的数据。 
(2).5、关闭资源。 
(2).6、代码体现

//接收端
import java.net.*;
class Demo1
{
	public static void main(String[] args)throws Exception
	{
		//建立udp socket服务,因为是要接收数据,必须要明确一个端口号。
	DatagramSocket ds=new DatagramSocket(10000);
	//创建一个字节数组
	byte[] by=new byte[1024];
	//创建数据包
	DatagramPacket dp=new DatagramPacket(by,by.length);
	//将接收的数据存储到数据包中。
	ds.receive(dp);
	byte[] buf=dp.getData();
	String s=new String(buf,0,dp.getLength());
	System.out.println(s);
	//关闭资源
	ds.close();

	
	
	}
}
三、TCP传输协议
1、TCP传输涉及的两个对象。客户端---->Socket ,服务端---->ServerSocket 
(1)、Socket常用的方法:
(1).1 Socket的构造方法:
 (1).1.1 public Socket(InetAddress address,int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 
 (1).1.2 public Socket(String host, int port)创建一个流套接字并将其连接到指定主机上的指定端口号。             
  (1).2 Socket的常用方法:
(1).2.1 public OutputStream getOutputStream()返回此套接字的输出流。                              
(1).2.2 public InputStream getInputStream()返回此套接字的输入流。 
(1).2.3 public void shutdownInput()此套接字的输入流置于“流的末尾”。
(1).2.4 public void shutdownOutput()禁用此套接字的输出流。                    
(2)、ServerSocket的常用方法:
(2).1 ServerSocket的构造方法:
     (2).1.1 public ServerSocket(int port)指定接收的客户端的端口.
(2).2 ServerSocket的常用方法:
(2).2.1 public Socket accept()侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。
2、TCP协议客户端和服务端
(1)、Tcp传输,客户端建立的过程。
思路:
(1).1、创建tcp客户端socket服务。使用的是Socket对象,建议该对象一创建就明确目的地。要连接的主机。    
(1).2、如果连接建立成功,说明数据传输通道已建立,该通道就是socket流 ,是底层建立好的。 既然是流,说明这里既有输入,又有输出。
想要输入或者输出流对象,可以找Socket来获取。可以通过getOutputStream(),和getInputStream()来获取两个字节流。
(1).3、使用输出流,将数据写出。
(1).4、关闭资源。
(1).5、代码体现

//TCP的客户端
import java.net.*;
import java.io.*;
class Demo4
{
	public static void main(String[] args)throws Exception
	{
		//创建tcp客户端socket服务
	Socket socket=new Socket("192.168.1.108",10003);
	//获取输入流
	OutputStream out=socket.getOutputStream();
	//使用输出流,将数据写出。
	out.write("你来了".getBytes());
	out.flush();
	//关闭资源
	out.close();
	}
}
	
(2)、建立tcp服务端
思路: 
(2).1、创建服务端socket服务。通过ServerSocket对象。 
(2).2、服务端必须对外提供一个端口,否则客户端无法连接。
(2).3、获取连接过来的客户端对象。 
(2).4、通过客户端对象获取socket流读取客户端发来的数据 ,并打印在控制台上。      
(2).5、关闭资源。关客户端,关服务端。 
(2).6、代码体现

//接收端
import java.io.*;
import java.net.*;
class Demo5
{
	public static void main(String[] args)throws Exception
	{
		//创建服务端socket服务。通过ServerSocket对象。 
	ServerSocket ss=new ServerSocket(10003);
	//获取连接过来的客户端对象。 
	Socket s=ss.accept();
	InputStream in=s.getInputStream();
	//通过客户端对象获取socket流读取客户端发来的数据 ,并打印在控制台上。
	BufferedReader br=new BufferedReader(new InputStreamReader(in));
	String sss=br.readLine();
	System.out.println(sss);
	//关闭资源
	br.close();
	ss.close();
	}
}
3、TCP传输案例
(1)、客户端文本文件,服务器输出是对客户端的反馈信息

代码体现

import java.io.*;  
import java.net.*;  
//客户端  
class  TcpClientDemo6 
{  
    public static void main(String[] args) throws Exception  
    {  
        //创建Socket服务  
        Socket s=new Socket("192.168.1.108",10004);  
        //定义读取流读去关联一个文件 
        BufferedReader br=new BufferedReader(new FileReader("Demo.java"));  
        //定义目的,将数据写入,发给服务端  
        PrintWriter pw=new PrintWriter(s.getOutputStream(),true);  
        //定义一个Socket读取流,读取服务端返回数据。  
        BufferedReader brin=new BufferedReader(new InputStreamReader(s.getInputStream()));  
        String line=null;  
        while ((line=br.readLine())!=null)  
        {  
            pw.println(line);  
        }  
         //关闭客户端的输出流。相当于给流中加入一个结束标记-1.  
        s.shutdownOutput();
		//接收返回信息  
        System.out.println(brin.readLine());
       //关闭资源   
        br.close();  
        s.close();  
    }  
}    
//服务端  
class TcpServerDemo6
{  
    public static void main(String[] args)throws Exception  
    {  
        //创建服务端的ServerSocket服务,并指定监听端口  
        ServerSocket ss =new ServerSocket(10004);  
        //获取客户端连接  
        Socket s=ss.accept(); 
        //读取Socket读取流中的数据  
        BufferedReader brin=new BufferedReader(new InputStreamReader(s.getInputStream()));  
        //将接收到的数据写入文件中  
        PrintWriter out=new PrintWriter(new FileWriter("Demo1.txt"),true);  
        //将返回信息写入Socket中  
        BufferedWriter bwout=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));  
        String line=null;  
        while ((line=brin.readLine())!=null)  
        {  
            out.println(line);  
        }  
		//写入,换行,刷新
        bwout.write("上传成功!");  
        bwout.newLine();
        bwout.flush();/  
		//关闭资源
        out.close();  
        s.close();  
        ss.close();  
    }  
}  

(2)、上传图片案例。

代码体现

//进行上传图片,客户端
import java.net.*;
import java.io.*;
class TCPClientDemo3
{
	public static void main(String[] args)throws IOException
	{
		//1 创建Socket服务  
		Socket s=new Socket("192.168.1.105",10012);
		//2创建读取类的对象来读取图片数据  
		FileInputStream fs=new FileInputStream("1.jpg");
		//3用Socket服务输出流写入数据  
		OutputStream out=s.getOutputStream();
		byte[] buf=new byte[1024];
		int ch=0;
		while ((ch=fs.read(buf))!=-1)
		{
			out.write(buf,0,ch);
		}
		//4关闭客户端的输出流。相当于给流中加入一个结束标记-1.  
		s.shutdownOutput();
		InputStream is=s.getInputStream();
		byte[] bu=new byte[1024];
		//5读取返回信息 
		int line=is.read(bu);
			String sr=new String(bu,0,line);
			System.out.println(sr);
		//关闭资源
		fs.close();
		s.close();
	}
}
//用于接收图片,服务端。
import java.net.*;
import java.io.*;
class TCPServerDemo3
{
	public static void main(String[] args)throws IOException
	{
	//1创建服务端的ServerSocket服务,并指定监听一个端口 
	ServerSocket ss=new ServerSocket(10012);
	//2 获取客户端对象  
	Socket s=ss.accept();
	//3 指定存放图片的一个目录
	File file=new File("d:\\java520\\day03");
	if (!(file.exists()))
	{
		file.mkdir();
	}
		int count=1;
		File fil=new File(file,count+"jpg");
		while (fil.exists())
		{
			count++;
			fil=new File(file,count+"jpg");
		}
	//4 用Socket服务读取流读取数据  
	InputStream is=s.getInputStream();
	//5创建输入类的对象来输入图片数据  
	FileOutputStream fs=new FileOutputStream(fil);
	byte[] buf=new byte[1024];
	int line=0;
	while ((line=is.read(buf))!=-1)
	{
		fs.write(buf,0,line);
	}
	//用Socket服务输出流写入数据  
	OutputStream out=s.getOutputStream();
	//反馈信息
	out.write("上传成功".getBytes());
	//out.fulse();
	//fs.close();
	//ss.close();
	
	
	}
}

(3)、客服端输入一个字符串,服务端把它转换成大写反馈给客服端

代码体现

import java.io.*;  
import java.net.*;  
class  TcpClientDemo7 
{  
    public static void main(String[] args) throws Exception  
    {  
        //创建Socket服务  
        Socket s=new Socket("192.168.1.108",10005);  
        //从键盘录入数据
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  
        //定义目的,将数据写入,发给服务端  
        PrintWriter pw=new PrintWriter(s.getOutputStream(),true);  
        //定义一个Socket读取流,读取服务端返回的大写数据。  
        BufferedReader brin=new BufferedReader(new InputStreamReader(s.getInputStream())); 
        String line=null;  
        while ((line=br.readLine())!=null)  
        {  
			//用来结束键盘录入的  
            if("over".equals(line))  
                break;      
            pw.println(line);
			////读取服务端返回的信息  
            String data=brin.readLine();
            System.out.println(data);  
        }  
		//关闭资源
        br.close();  
        s.close();  
    }  
}  
class TcpServerDemo7 
{  
    public static void main(String[] args)throws Exception  
    {  
        //创建服务端的ServerSocket服务,并指定监听一个端口  
        ServerSocket ss =new ServerSocket(10005);  
        //获取客户端连接  
        Socket s=ss.accept();  
        //读取Socket读取流中的数据  
        BufferedReader brin=new BufferedReader(new InputStreamReader(s.getInputStream()));  
        //将大写数据写入,并发送给客户端。  
        PrintWriter pw=new PrintWriter(s.getOutputStream(),true); 
        String line=null;  
        while ((line=brin.readLine())!=null)  
        {  
            System.out.println(line);  
			//将读到数据转换为大写后在返回 
            pw.println(line.toUpperCase()); 
        }  
		//关闭资源
        s.close(); 
        ss.close();  
    }  
}  

(4)、TCP传输容易出现的问题:

(4).1、客户端连接上服务端,两端都在等待,没有任何数据传输。
(4).2、通过例程分析:
因为read方法或者readLine方法是阻塞式。
(4).3、解决办法:
自定义结束标记,使用shutdownInput,shutdownOutput方法。
4、常见的网络架构:
(1)、C/S: client / server  
特点:
(1).1、程序员需要开发客户端和服务端。
(1).2、维护较为麻烦。
(1).3、将一部分运算转移到客户端来完成,减轻服务器端的压力。
(2)、B/S: browser / server
特点:
(2).1、程序员只需要开发服务端。客户端使用系统已有的浏览器即可。
(2).2、维护很简单。只需要维护服务端。
(2).3、所有的运算的都在服务端。

(3)、目前流行BS

------- android培训、java培训、期待与您交流! ----------

你可能感兴趣的:(java,学习日记)