黑马程序员———网络编程

来源:互联网 发布:淘宝假货 猪哼少 编辑:程序博客网 时间:2024/05/24 04:22

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

网络编程

网络编程模型:

网络通讯过程:

1、找到对方的IP

2、数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都进行标识。为了方便

称呼这个数字,叫做端口。逻辑端口

3、定义通信规则。这个通信规则成为协议。国际组织定义了通用协议TCP/IP

对象介绍:

InetAddress:此类表示互联网协议 (IP) 地址。

常用方法:

static InetAddress getByName(String host) 给定主机名的情况下,确定主机的IP地址

static InetAddress getLocalHost() 返回本地主机

String getHostAddress() 返回IP地址字符串

String getHostName() 获取此IP地址的主机名

UDP编程

DatagramSocketDatagramPacket

建立发送端接收端

建立数据包

调用Socket的发送接收方法

关闭Socket

发送端与接收端是两个独立的运行程序

UDP方法介绍:

构造方法: DatagramSocket()   构造数据报套接字并将其绑定到本地主机上任何可用的端口。

DatagramSocket() 创建数据报套接字并将其绑定到本地主机上的指定端口。

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

void receive(DatagramPacket p)    从此套接字接收数据报包。

DatagramPacket 构造函数:

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

DatagramPacket(byte[] buf, int length,InetAddress address,int port)  构造数据报包,用来将长度为length 的包发送到
指定主机上的指定端口号。

方法:InetAddress getAddress()返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。

byte[]  getDate() 返回数据缓冲区。

int getLength() 返回将要发送或接收到的数据的长度。

int getPort() 返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。

小练习UDP发送:

<span style="font-size:18px;">/*需求:通过UDP传输方式,将一段文字数据发送出去 * 思路: * 1,建立udpSocket服务 * 2,提供数据,并将数据封装到数据包中 * 3,通过Socket服务的发送功能,将数据包发出去 * 4,关闭资源*/package Test;import java.net.*;public class UDPSendDemo {public static void main(String[] args)throws Exception {//通过DatagramSocket对象,创建UDP服务DatagramSocket ds = new DatagramSocket();//确定数据,并封装成数据包byte[] buf = "UDP ge men lai le".getBytes();DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10000);//通过Socket服务,将已有的数据包发送出去,通过Send方法ds.send(dp);//关闭资源ds.close();}}</span>


UDP接收:

<span style="font-size:18px;">/*需求:定义一个应用程序,用于接受udp协议传输的数据并处理 * 思路 * 1,定义udpsocket服务,通常会监听一个端口。其实就是给这个接受网络应用程序定义一个数字标识 * ,方便于明确哪些数据过来该应用程序可以处理 * 2,定义一个数据包,因为要存储接收到的字节数据。因为数据包对象中有更多功能可以提取字节数据中的不同数据星系 * 3,通过socket服务的receive方法将接受的数据数据存入已定义好的数据包中 * 4,通过数据包对象的热油功能,将这些不同的数据取出,打印在控制台上。 * 5,关闭资源 * */package Test;import java.net.*;public class UDPReceiveDemo {public static void main(String[] args)throws Exception {//创建udpsocket,建立站点DatagramSocket ds = new DatagramSocket(10000);byte[] buf = new byte[1024];//定义数据包 用于存储数据DatagramPacket dp = new DatagramPacket(buf,buf.length);//通过服务的receive方法将受到的数据存入数据包中ds.receive(dp);//通过数据包的方法获取其中的数据String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());int port = dp.getPort();System.out.println(ip+":"+data+":"+port);//关闭资源ds.close();}}</span>

UDP聊天程序:

<span style="font-size:18px;">package Inte;/* * 编写一个聊天程序 * 有收数据的部分和发数据的部分 * 这两部分都需要执行 * 那就需要用到多线程的技术 * 一个线程控制收,一个线程控制发。 * 因为收和发动作时不一致的,所以要定义两个run方法 * 而且这两个方法要封装不同的类中 */import java.net.*;import java.io.*;public class ChatDemo {public static void main(String[] args) throws Exception{//多线程 运行发送端 和接收端DatagramSocket sendSocket = new DatagramSocket();DatagramSocket receSocket = new DatagramSocket(10005);new Thread(new Send(sendSocket)).start();new Thread(new Rece(receSocket)).start();}}class Send implements Runnable{//创建udp服务,通过DatagramSocket对象private DatagramSocket ds;public Send(DatagramSocket ds){this.ds = ds;}@Overridepublic void run() {try{//接受键盘数据BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line = bufr.readLine()) != null){//读取键盘数据if("886".equals(line))break;byte[] buf = line.getBytes();//确定数据,并封装成数据包DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10005);//通过socket服务,将已有的数据包发送出去,通过send方法ds.send(dp);}}catch(Exception e ){throw new RuntimeException("发送错误");}}}class Rece implements Runnable{//创建udp socket 建立端点private DatagramSocket ds;public Rece(DatagramSocket ds){this.ds = ds;}@Overridepublic void run() {try{while(true){byte[] buf = new byte[1024];//定义数据包 用来存储数据DatagramPacket dp = new DatagramPacket(buf,buf.length);//通过服务的receive方法将收到的数据存入数据包中ds.receive(dp);//通过数据包的方法获取其中的数据String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());System.out.println(ip+":"+data);}}catch(Exception e){throw new RuntimeException("接收端错误");}}}</span>

TCP传输

Socket和ServerSocket

建立客户端和服务器端

建立连接后,通过Socket中的IO流进行数据的传输

关闭Socket

同样,客户端和服务器端是两个独立的应用程序

Socket :此类实现客户端套接字(也可以就叫套接字)。套接字是两台机器间通信端点。

构造函数:Socket(InetAddress address , int port)  创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

方法: InputStream getInputStream()  返回此套接字的输入流。

OutputStream getOutputStream() 返回此套接字的输出流

InetAddress getInetAddress() 返回套接字连接的地址

ServerSocket 构造函数:

ServerSocket(int port) 创建绑定到特定端口的服务器套接字

方法;Socket accept() 侦听并接受到此套接字的连接。

 

TCP客户端:

客户端编程步骤:1、建立Socket服务,指定要连接主机和端口2、获取Socket流中的输出流,将数据发送到该流中,通过网络发送给服务端3、关闭客户端资源package Inte;import java.net.*;import java.io.*;public class TcpClient {public static void main(String[] args) throws Exception, IOException {//创建客户端的socket服务,指定目的的主机和端口Socket s = new Socket("127.0.0.1",10000);//为了发送数据,获取socket流中的输出流OutputStream out =s.getOutputStream();//写入out.write("ge men lai le ".getBytes());//关闭客户端sockets.close();}}

TCP服务端:

服务端步骤1、建立服务器Socket服务,并监听一个端口2、通过accept方法获取连接过来的客户端对象3、获取客户端发送过来的数据,使用客户端对象的读取流来读取数据4、关闭客户端 服务端package Inte;import java.net.*;import java.io.*;public class TcpServer {public static void main(String[] args) throws Exception {//建立服务端socket服务,并监听一个端口ServerSocket ss = new ServerSocket(10000);//通过accept方法获取连接过来的客户端对象Socket s =ss.accept();String ip =s.getInetAddress().getHostAddress();System.out.println(ip+".....connected");//获取客户端发送过来的数据,使用客户端对象的读取流来读取数据InputStream in = s.getInputStream();byte [] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf,0,len));//关闭客户端s.close();ss.close();}}

TCP复制文件:

 

客户端package Inte;import java.net.*;import java.io.*;public class TestClient {public static void main(String[] args) throws Exception {//建立客户度SocketSocket s = new Socket("127.0.0.1",10006);//数据读取流BufferedReader bufr = new BufferedReader(new FileReader("D:\\javasl\\Test\\src\\Inte\\ChatDemo.java"));//Socket输出流PrintWriter out = new PrintWriter(s.getOutputStream(),true);String line = null;//输出while((line = bufr.readLine()) != null){out.println(line);}//禁止套接字输出流s.shutdownOutput();//Socket读取流BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));String str = bufIn.readLine();//打印服务器回送过来的数据System.out.println(str);//关闭流bufr.close();//关闭客户端s.close();}}
服务端package Inte;import java.net.*;import java.io.*;public class TestServer {public static void main(String[] args) throws Exception {//建立服务端socketServerSocket ss = new ServerSocket(10006);//获取客户度SocketSocket s =ss.accept();//打印输出连接的客户端IP地址String ip =s.getInetAddress().getHostAddress();System.out.println(ip+".....connected");//读取流BufferedReader buf = new BufferedReader(new InputStreamReader(s.getInputStream()));//文件输入流PrintWriter out = new PrintWriter(new FileWriter("D:\\javasl\\Test\\src\\Inte\\server.txt"));String line = null;//写入while((line = buf.readLine()) != null){out.write(line);}PrintWriter pw = new PrintWriter(s.getOutputStream(),true);//给客户端回送数据 pw.println("上传成功");//关闭流和客户端 服务端out.close();s.close();ss.close();}}

TCP上传图片

客户端package Inte;import java.net.*;import java.io.*;public class PicClient {public static void main(String[] args)throws Exception {//判读参数长度是否为一if(args.length != 1){System.out.println("请选择一个jpg格式的文件");return;}//用此参数创造文件File file = new File(args[0]);//判断问价你是否存在以及是否为文件if(!(file.exists()&&file.isFile())){System.out.println("文件有问题");return;}//判断文件是否为jpg文件if(!file.getName().endsWith(".jpg")){System.out.println("图片格式错误");return;}//判断文件大小是否大于3MBif(file.length() > 1034*1024*3){System.out.println("文件过大");return;}//创建客户端SocketSocket s = new Socket("127.0.0.1",10003);//读取客户端要上传的图片文件FileInputStream fis = new FileInputStream(file);//获取Socket输出流,将读到的图片数据发送给服务端OutputStream out = s.getOutputStream();byte[] buf = new byte[1024];int len = 0;while((len = fis.read(buf)) != -1){out.write(buf, 0, len);}//告诉服务端说,这边的数据发送完毕。让服务器停止读取s.shutdownOutput();//InputStream in = s.getInputStream();//byte [] bufIn = new byte[1024];//int num = 0;//num  = in.read(bufIn);//读取服务端发回的内容BufferedReader bufn = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;line = bufn.readLine();System.out.println(line);//关闭流与客户端fis.close();s.close();}}
服务端package Inte;import java.net.*;import java.io.*;public class PicServer {public static void main(String[] args)throws Exception {ServerSocket ss = new ServerSocket(10003);while(true){Socket s = ss.accept();new Thread(new PicThread(s)).start();}}}class PicThread implements Runnable{//创建TCP的Socket服务端private Socket s ;public PicThread(Socket s ){this.s = s;}@Overridepublic void run() {int count = 1;String ip = s.getInetAddress().getHostAddress();try{System.out.println(ip+"....connected");//读取客户端发来的数据InputStream in = s.getInputStream();//定义文件名File file = new File("D:\\"+ip+"("+(count)+")"+".jpg");while(file.exists())file = new File("D:\\"+ip+"("+(count++)+")"+".jpg");//将读取到的数据存储到一个文件中FileOutputStream fos = new FileOutputStream(file);byte[] buf = new byte[1024];int len = 0;while((len = in.read(buf)) != -1){fos.write(buf, 0, len);}//OutputStream out = s.getOutputStream();//out.write("上传成功".getBytes());//给客户端回送传送结果数据PrintWriter pw = new PrintWriter(s.getOutputStream(),true);pw.println("上传成功");//关闭流 关闭客户端fos.close();s.close();}catch(Exception e){}}}

登陆

客户端:

<span style="font-size:18px;">package Inte;import java.net.*;import java.io.*;public class LoginClient {public static void main(String[] args) throws Exception {//建立客户端SocketSocket s = new Socket("127.0.0.1",10007);//键盘录入BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//获取Socket输出流PrintWriter out = new PrintWriter(s.getOutputStream(),true);//获取Socket读取流BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));for(int x = 0 ; x < 3 ; x++){//读取键盘录入的用户名String line = bufr.readLine();if(line == null)break;//将用户名发送到服务端out.println(line);//读取服务端回送数据String info = bufIn.readLine();System.out.println(info);if(info.contains("欢迎"))break;}bufr.close();s.close();}}</span>

服务端

<span style="font-size:18px;">package Inte;import java.net.*;import java.io.*;public class LoginServer {public static void main(String[] args) throws Exception {//创建服务端Socket  并监听007端口ServerSocket ss = new ServerSocket(10007);while(true){//获取连接的客户端SocketSocket s = ss.accept();new Thread(new UserThread(s)).start();}}}class UserThread implements Runnable {private Socket s ;public UserThread(Socket s){this.s =s ;}@Overridepublic void run() {//获取连接但服务端的ipString ip = s.getInetAddress().getHostAddress();System.out.println(ip+"connected");try{for(int x = 0; x<3; x++){//获取Socket读取流BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));String name = bufIn.readLine();//如果读取的数据为空 则程序结束if(name == null)break;//读取存放用户名的文件BufferedReader bufr =new BufferedReader(new FileReader("D:\\a.txt"));//获得客户端Socket输出流PrintWriter out = new PrintWriter(s.getOutputStream(),true);String line = null;boolean flag = false;//将服务端传过来的用户名与文件中的用户名一一对比,想同则将flag置为truewhile((line = bufr.readLine()) != null){if(line.equals(name)){flag =true;break;}}//如果用户名存在 服务端显示xxx,已登录 并且把xxx。欢迎登陆发送到客户端显示if(flag){System.out.println(name+"已登录");out.println(name+",欢迎光临");break;}//用户名不存在 服务端显示xxx,尝试登陆,把用户名xxx,不存在发送到客户端 显示else{System.out.println(name+"尝试登陆");out.println("用户名"+name+"不存在");}}}catch(Exception e){throw new RuntimeException(ip+"尝试失败");}}}</span>

自定义浏览器

<span style="font-size:18px;">package Test3;import java.io.*;import java.net.*;public class MyIE {public static void main(String[] args) throws Exception{//建立客户端Socket服务Socket s = new Socket("122.207.132.49", 8080);//获取Socket输出流PrintWriter pw = new PrintWriter(s.getOutputStream(),true);//模拟浏览器给服务器发送相应数据pw.println("GET /MyWeb/1.html HTTP/1.1");pw.println("Accept: text/html, application/xhtml+xml, */*");        pw.println("Accept-Language: zh-CN");        pw.println("Accept-Encoding: gzip, deflate");        pw.println("Host: 122.207.132.49:10011");        pw.println("Connection: closed");        pw.println();        pw.println();        //Socket读取流        InputStream in = s.getInputStream();        byte[] buf = new byte[1024];        int len = 0;        //读服务器发过来的数据        len =in.read(buf);        //将数据打印到控制台上        System.out.println(new String(buf,0,len));}}</span>

URL:类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对

更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

构造函数:URL(string spec)  根据 String 表示形式创建URL 对象。

方法:String getFile() 获取此 URL 的文件名。

String getHost() 获取此 URL 的主机名(如果适用)。

String getPath() 获取此 URL 的路径部分。

int getPort()  获取此 URL 的端口号。

String getProtocal()  获取此 URL 的协议名称。

String getQuery()  获取此 URL 的查询部分。

URLConnection openConnection()   返回一个URLConnection 对象,它表示到URL 所引用的远程对象的连接。

URLConnection的方法:InputStream getInputStream() 返回从此打开的连接读取的输入流。

练习方法:

package Test3;import java.net.*;import java.io.*;public class URlDemo {public static void main(String[] args)throws Exception {//创建URL对象URL url = new URL("http://122.207.132.49:8080/MyWeb/1.html?name=fdl");//获取协议String protocal = url.getProtocol();//获取主机String host = url.getHost();//获取端口号int    port = url.getPort();//获取路径String path = url.getPath();//获取文件String file = url.getFile();//获取查询String Qu   = url.getQuery();System.out.println("protocal: "+protocal);System.out.println("host: "+host);System.out.println("port: "+port);System.out.println("path: "+path);System.out.println("file: "+file);System.out.println("Qu: "+Qu);URL url_1 = new URL("http://122.207.132.49:8080/MyWeb/1.html");//得到URL连接对象URLConnection  connection= url_1.openConnection();//获取连接对象的输入流InputStream in = connection.getInputStream();//缓冲byte[] buf = new byte[1024];//读int len = in.read(buf);System.out.println(new String(buf,0,len));}}


 

 

 

 

 

 

 

 

 




 

 



 

 



 


 

 




 

 

 

 

 

 

 

 

 

 

 

 

 

0 0