黑马程序员_网络编程
来源:互联网 发布:辗转相减法 vb 编辑:程序博客网 时间:2024/05/12 12:30
-------android培训、java培训、期待与您交流!-------
网络编程
1、网络编程基础知识
(1)网络主要功能
A、资源共享
B、信息传输与集中处理
C、均衡负荷与分布处理
D、综合信息服务
(2)网络通讯要素
A、传输协议
目前的写有OSI与TCP/IP,OSI把计算机网络分为七层,TCP/IP协议将网络分为四层。
OSI模型
应用层
表示层
会话层
传输层
网络层
数据连接层
物理层
TCP/IP模型
应用层
传输层
网际层
主机至网络层
B、IP地址
概述:IP地址用于唯一地标识网络中的一个通信实体,这个通信实体可以是一台主机、打印机、路由端口等。
IP地址 = 网络号码+主机地址
A类:1.0.0.1---127.255.255.254 10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)
B类:128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。
C类:192.0.0.1---223.255.255.254 192.168.X.X是私有地址
D类:224.0.0.1---239.255.255.254
E类:240.0.0.1---247.255.255.254
※注意:
1)127.0.0.1 回环地址,可用于测试本机的网络是否有问题. ping 127.0.0.1
IP地址不能够是广播地址或者网络地址,所以要遵守如下规则:
IP地址网络地址不能全部设置为“1”或“0”
IP地址子网地址不能全部设置为“1”或“0”
IP地址主机地址不能全部设置为“1”或“0”
2)E类地址是保留地址。
C、端口号
端口号是一个十六位整数,用于表示数据交给那个通信程序处理。端口就是应用程序与外界交流的出入口,它是一种抽象的软件结构,包括一些数据结构和I/O缓冲区。
0-1023为公认端口。他们紧密绑定一些特定服务。
1024-49151为注册端口。应用程序应该使用这个范围的端口。
49152-65535为动态或者私有端口,这些端口是应用程序使用的动态端口,应用程序一般不会主动使用这些端口。
(3)网络通讯前提:
A、找到对方IP数据要发送到指定端口。为了标示不同的应用程序,所以给这些网络应用程序都用数字进行标识。这个表示就叫端口。
B、定义通信规则。这个规则称为通信协议,国际组织定义了通用协议TCP/IP
2、TCP和UDP
(1)UDP和TCP的区别:
A、UDP
将数据及源和目的封装成数据包中,不需要建立连接
每个数据报的大小在限制在64k内
因无连接,是不可靠协议
不需要建立连接,速度快
B、TCP
建立连接,形成传输数据的通道。
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
注:三次握手:
第一次:我问你在么?
第二次:你回答在。
第三次:我反馈哦我知道你在。
3、Socket(UDP传输)
要点:
Socket就是为网络服务提供的一种机制。
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。
玩Socket主要就是记住流程,代码查文档就行
4、UDP传输:DatagramSocket与DatagramPacket
A、发送端:
建立DatagramSocket服务;
提供数据,并将数据封装到字节数组中;
创建DatagramPacket数据包,并把数据封装到包中,同时指定IP和接收端口
通过Socket服务,利用send方法将数据包发送出去;
关闭DatagramSocket和DatagramPacket服务。
B、接收端:
建立DatagramSocket服务,并监听一个端口;
定义一个字节数组和一个数据包,同时将数组封装进数据包;
通过DatagramPacket的receive方法,将接收的数据存入定义好的数据包;
通过DatagramPacke相关的方法,获取发送数据包中的信息;
关闭DatagramSocket和DatagramPacket服务。
C、DatagramSocket与DatagramPacket方法摘要:
(1)构造方法:
DatagramSocket()
构造数据报套接字并将其绑定到本地主机上任何可用的端口。
DatagramSocket(int port)
创建数据报套接字并将其绑定到本地主机上的指定端口。
DatagramSocket(int port, InetAddress laddr)
创建数据报套接字,将其绑定到指定的本地地址。
(2)方法摘要:
void close()//关闭此数据报套接字。
InetAddress getInetAddress()// 返回此套接字连接的地址。
InetAddress getLocalAddress() //获取套接字绑定的本地地址。
int getPort() //返回此套接字的端口。
void receive(DatagramPacket p) //从此套接字接收数据报包。
void send(DatagramPacket p) //从此套接字发送数据报包。
D、DatagramPacket
(1)构造方法:
DatagramPacket(byte[] buf, int length) //构造 DatagramPacket,用来接收长度为 length 的数据包。
DatagramPacket(byte[] buf, int length, InetAddress address, int port) //构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
InetAddress getAddress()//返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。
byte[] getData() //返回数据缓冲区。
int getLength() //返回将要发送或接收到的数据的长度。
int getPort() //返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。
典型例题:
发送端:
package net;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public class UdpSend{/** * 需求:通过UDP方式,将一段文字数据发送出去。1.首先建立一个UDPSocket服务 2.提供数据将数据封装到包中3.通过Socket服务将数据发出。4.关闭Socket服务; * @param args */public static void main(String[] args) throws Exception{//1、创建UDP服务,通过DatagramSocket对象DatagramSocket ds = new DatagramSocket(8888);byte[] buf = "sdfsdfsdf".getBytes();//2、确定数据并且封装成数据包DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.0.104"), 20000);ds.send(dp);//3、使用已经存在的Socket服务,将数据包对象发送出去ds.close();//4、使用已经存在的UDPSocket服务将数据关闭}}
接收端:
package net;import java.net.DatagramPacket;import java.net.DatagramSocket;public class UDPRece{/** * 需求:定义应用程序,用于接收udp协议传输的数据并处理。 1.定义一个UDPSocket服务。 * 2.定义一个数据包,因为要存取接收到的字节数据,因为数据包对象中封装有多种方法,方便我们提取字节数据中的内容。 * 3.通过UDPSocket服务,调用receive()方法将 接收到的数据存入数据包中。 * 4.通过数据包特有的方法,将我们需要的数据提取出来打印在控制台上。 5.关闭资源。 * * @param args */public static void main(String[] args) throws Exception{DatagramSocket ds = new DatagramSocket(20000);byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, buf.length);ds.receive(dp);String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());System.out.println("IP="+ip+"--data="+data+"---prot="+dp.getPort());}}
需求:编写简单的聊天工具
思路:使用多线程技术
发送端:
class UDPSend implements Runnable{private DatagramSocket ds;public UDPSend(){}public UDPSend(DatagramSocket ds){this.ds=ds;}public 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[] buff = line.getBytes();DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.104"),10001);ds.send(dp);}}catch(Exception e){throw new RuntimeException("发送失败");}}}
接收端:
class UDPRece implements Runnable{private DatagramSocket ds;public UDPSend(){}public UDPSend(DatagramSocket ds){this.ds=ds;}public void run(){try{while(true){byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);ds.receive(dp);//将发送端发送的数据包接收到接收端的数据包中String ip = dp.getAddress().getHosyAddress();//获取发送端的ipString data = new String(dp.getData(),0,dp.getLength());//获取数据int port = dp.getPort();//获取发送端的端口号sop(ip+":"+data+":"+port);}}catch(Exception e){throw new RuntimeException("接收失败");}}}
测试类:
class UDPTest{public static void main(String[] args){DatagramSocket sendSocket = new DatagramSocket();DatagramSocket receSocket = new DatagramSocket(10001);new Thread(new UDPSend(sendSocket)).start();new Thread(new UDPRece(receSocket)).start();}}
5、TCP传输
Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket
同样,客户端与服务器端是两个独立的应用程序。
(1)Socket
A、构造方法:
Socket() //通过系统默认类型的 SocketImpl 创建未连接套接字
Socket(InetAddress address, int port)//创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
Socket(String host, int port) //创建一个流套接字并将其连接到指定主机上的指定端口号。
B、方法摘要:
void close() //关闭此套接字。
InetAddress getInetAddress() ///返回套接字连接的地址。
InputStream getInputStream() //返回此套接字的输入流。
OutputStream getOutputStream() //返回此套接字的输出流。
int getPort() //返回此套接字连接到的远程端口。
void shutdownInput() //此套接字的输入流置于“流的末尾”。
void shutdownOutput() // 禁用此套接字的输出流。
String toString() //将此套接字转换为 String。
(2)ServerSocket
A、构造方法:
ServerSocket() //创建非绑定服务器套接字。
ServerSocket(int port) //创建绑定到特定端口的服务器套接字。
B、方法摘要:
Socket accept() //侦听并接受到此套接字的连接。
void close() //关闭此套接字。
InetAddress getInetAddress() //返回此服务器套接字的本地地址。
(3)TCP传输流程:
客户端:
建立Socket服务,并制定要连接的主机和端口;
获取Socket流中的输出流OutputStream,将数据写入流中,通过网络发送给服务端;
获取Socket流中的输出流InputStream,获取服务端的反馈信息;
关闭资源。
服务端:
建立ServerSocket服务,并监听一个端口;
通过ServerSocket服务的accept方法,获取Socket服务对象;
使用客户端对象的读取流获取客户端发送过来的数据;
通过客户端对象的写入流反馈信息给客户端;
关闭资源;
(4)典型例题:
例1:客户端
package net;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;public class TcpClient2{/** * 需求:从键盘录入数据,通过Tcp协议向服务端发送,服务端接收到后将数据转换成大写字母,然后返回给用户。 * 数据可以实现不断录入、当遇到指定over字符的时候停止。 * * @param args */public static void main(String[] args) throws Exception{ // 新建一个客户端套接字服务,同时指定目的IP与接收端口Socket socket = new Socket("192.168.0.104", 10004);// 新建一个键盘的录入的缓冲区BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));// 定义一个套接字通信的输入流的缓冲区PrintWriter printWriter=new PrintWriter(socket.getOutputStream(),true);BufferedReader bufr1 = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 定义一个套接字通信的输出流的缓冲区//BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));String str;// 实现从键盘读取数据然后向套接字通信的输出流输出while ((str = bufr.readLine()) != null){printWriter.println(str);//bufw.write(str);//bufw.newLine();// 向Socket通信的输出流中输入一个换行标记//bufw.flush();// 刷新缓冲区//1、会不会数据还没有返回就已经执行ufr1.readLine(),然后输出的结果为空?String msg = bufr1.readLine();//A、从服务端读取数据System.out.println("Client=" + msg);//B、打印输出的结果}/* * 2、把 A、B出的代码注释掉、换成如下代码为什么没结果? * * String str1; while ((str1 = bufr1.readLine()) != null) { * System.out.println(str1); } */bufr.close();socket.close();}}
服务端:
package net;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class TcpServer2{/** * @param args */public static void main(String[] args) throws Exception{// 建立服务套接字,同时指定监听的端口ServerSocket ss = new ServerSocket(10004);// 获取客户端的套接字Socket s = ss.accept();// 打印服务端的IPSystem.out.println("serverprot----" + s.getInetAddress().getHostAddress());// 定义一个套接字通信的输入流的缓冲区BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));// 定义一个套接字通信的输出流的缓冲区PrintWriter printWriter = new PrintWriter(s.getOutputStream(), true);// BufferedWriter bufw = new BufferedWriter(new// OutputStreamWriter(s.getOutputStream()));String str1;while ((str1 = bufr.readLine()) != null)// 从输入缓冲区中读取数据,然后将其转换为大写字母{System.out.println("Server端接收的数据=" + str1);printWriter.println(str1.toUpperCase());// bufw.write(str1.toUpperCase());// bufw.newLine();// bufw.flush();// 刷新缓冲区// bufw.close();}s.close();// 关闭套接字,因为套接字与输入、输出流相关。只要关闭套接字。就不需要在关闭输入、输出流ss.close();// 关闭服务端端套接字}}
例2、客户端:
package net;import java.io.*;import java.net.*;class PicClient1{/*客户端。1,定义服务端点。2,读取客户端已有的图片数据。3,通过socket 输出流将数据发给服务端。4,读取服务端反馈信息。5,关闭。*/public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.0.104", 10007);FileInputStream fis = new FileInputStream("E:\\1.jpg");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 = in.read(bufIn);System.out.println(new String(bufIn, 0, num));fis.close();s.close();}}
服务端:
package net;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;class PicThread implements Runnable{/*/*服务端这个服务端有个局限性。当A客户端连接上以后。被服务端获取到。服务端执行具体流程。这时B客户端连接,只有等待。因为服务端还没有处理完A客户端的请求,还有循环回来执行下次accept方法。所以暂时获取不到B客户端对象。那么为了可以让多个客户端同时并发访问服务端。那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。如何定义线程呢?只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中。*/*/private Socket s;PicThread(Socket s){this.s = s;}public void run(){int count = 1;String ip = s.getInetAddress().getHostAddress();try{System.out.println(ip + "....connected");InputStream in = s.getInputStream();// File dir = new File("d:\\pic");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());fos.close();s.close();} catch (Exception e){throw new RuntimeException(ip + "上传失败");}}}class PicServer1{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10007);while (true){Socket s = ss.accept();new Thread(new PicThread(s)).start();}// ss.close();}}
6、URL的总结:
(1)概述:
URL(Uniform Resource Locator)称为统一资源定位器,它是指向互联网“资源的指针”。资源可以是简单的文件或目录,也可以是对更为复杂对象的引用。JDK中还提供了一个URI(Uniform Resource Identifiers)类们其实例代表一个统一资源标识符,Java的URI不能用于定位任何资源,它的唯一作用就是解析。URL则包含一个可打开到达该资源的输入流,我们可以将URL理解成URI的特例。
URL对象的常用方法:
String getFile():获取该URL的资源名
String getHost():获取该URL的主机名
String getPath():获取该URL的路径部分
int getPort();获取该URL的端口号
String getProtocol():获取该URL的协议名称
String getQuery():获取该URL的查询字符串部分。
URLConnection openConnection()返回一个URLConnection对象,他代表了与URL所引用的远程对象的连接。
InputStream openStream():打开与此URL的连接,并返回一个用于读取该URL资源的InputStream
-------android培训、java培训、期待与您交流!-------
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 黑马程序员_网络编程
- 教大家用java实现顶一下踩一下功能
- boost 线程学习bind
- 程序员怎么样才能提高
- 代码大全读书笔记(1)
- 到2013年5月份的android不同版本市场占有率
- 黑马程序员_网络编程
- JAVA的Random类(转)
- HDU 1160
- 产品软文模板
- 输入输出流(字符)的简单实例
- 单词数,hdu2072
- Linux int lstat(const char *path, struct stat *buf);
- 这个论坛好高级
- 很有意思的软件产品宣传画,这个美工很有创意