黑马程序员_java学习日记_Java基础_网络编程
网络通信步骤
1 找到对方IP
2 数据要发送到对方指定的应用程序上,为了标识这些程序,所以给这些网络应用程序用数字进行了标识,为了方便标识,叫做端口
3 定义一个通信规则,称之为协议
127.0.0.1本地回环地址
开放系统互联参考模型
TCP/IP参考模型
数据封包:按照每一层加上每一层的信息
数据拆包:
应用层:HTTP协议 FTP
传输层:TCP UDP
网络层:IP
我们要做的是用java操作IP,端口号,传输协议
publicstaticvoid main(String[] args) throws UnknownHostException {
?????? InetAddress i = InetAddress.getLocalHost();
?????? String name = i.getHostName();
?????? String address = i.getHostAddress();
?????? //以IP为主,因为主机名还需要解析
?????? InetAddress j = InetAddress.getByName("www.baidu.com");
?????? System.out.println(j.getHostName());
?????? //如果该地址和对应的主机名不存在,则解析不成功于是名字还是IP地址
?????? System.out.println(j.getHostAddress());
??? }
端口就是一个数字
UDP和TCP的区别
UDP:面向无连接,打包发送数据,每个包64K,不需要建立连接,速度快,不可靠
TCP:面向连接,数据传输量大,需要建立连接,速度慢效率低,可靠
三次握手
Socket编程:网络服务提供的一中机制
通信两端都有socket
数据两端通过IO传输
思路
发送端
publicstaticvoid main(String[] args) throws IOException {
?????? //创建socket服务
?????? DatagramSocket d = new DatagramSocket();
?????? //确定数据封包
?????? byte[] b = "asdsadasda".getBytes();
?????? DatagramPacket d1 = new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 10000);
?????? //发送数据
?????? d.send(d1);
?????? //关闭
?????? d.close();
??????
??? }
接收端(在定义接收端通常都会监听一个端口,其实就是给网络应用程序定义一个标识,方便明确哪些数据过来,该应用程序可以处理)
publicstaticvoid main(String[] args) throws IOException {
?????? //创建socket接收点
?????? DatagramSocket p = new DatagramSocket(10000);
?????? //定义数据包存储数据
?????? byte[] b = newbyte[1024];
?????? DatagramPacket d = new DatagramPacket(b,b.length);
?????? //接受数据
?????? p.receive(d);
?????? String ip = d.getAddress().getHostAddress();
?????? String name = d.getAddress().getHostAddress();
?????? String com = new String(d.getData(),0,d.getLength());
?????? int port = d.getPort();
?????? System.out.println(ip+"!"+name+"!"+port);
?????? System.out.println(com);
??? }
键盘录入
publicstaticvoid main(String[] args) throws IOException {
?????? //创建socket服务
?????? DatagramSocket d = new DatagramSocket();
?????? //确定数据封包
?????? BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
?????? byte[] b = newbyte[1024];
?????? //br.read(b);
?????? String str = null;
?????? while((str = br.readLine())!= null)
?????? {
?????????? if("886".equals("line"))
????????????? break;
?????????? else
?????????? {
????????????? b = str.getBytes();
????????????? DatagramPacket d1 = new DatagramPacket(b, b.length, InetAddress.getByName("192.168.1.102"), 10000);
????????????? //发送数据
????????????? d.send(d1);?????????????
?????????? }
?????? }
?????? //关闭
?????? d.close();
??????
??? }
192.168.1.0 和192.168.1.255没法用 255是广播地址
多线程:一个线程接收数据,一个线程发送数据
山寨QQ
//发送端socket
class send implements Runnable
{
??? private DatagramSocket d;
??? public send(DatagramSocket d)
??? {
?????? this.d = d;
??? }
??? @Override
??? publicvoid run() {
?????? try
?????? {
?????????? BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
?????????? String str = null;
?????????? while((str = br.readLine())!= null)
?????????? {
????????????? byte[] b = str.getBytes();
????????????? DatagramPacket dp = new DatagramPacket(b, b.length,InetAddress.getByName("192.168.1.255"),10001);
????????????? d.send(dp);
?????????? }
?????? }catch(Exception e){
?????????? thrownew RuntimeException("发送失败");
?????? }finally{
?????????? d.close();???????
?????? }
??????
??? }
}
//接收端socket
class receive implements Runnable
{
??? private DatagramSocket d;
??? public receive(DatagramSocket d)
??? {
?????? this.d = d;
??? }
??? @Override
??? publicvoid run() {
?????? try
?????? {
?????????? while(true)
?????????? {????????????
????????????? byte[] b = newbyte[1024];
????????????? DatagramPacket dp = new DatagramPacket(b, b.length);
????????????? d.receive(dp);
????????????? String str = dp.getAddress().getHostAddress();
????????????? String data = new String(dp.getData(),0,dp.getLength());
????????????? System.out.println(str+"=="+data);
?????????? }
?????? }catch(Exception e){
?????????? thrownew RuntimeException("发送失败");
?????? }finally{
?????????? d.close();???????
?????? }
??????
??? }
}
publicclass FakeQQ {
?
??? publicstaticvoid main(String[] args) {
?????? try {
?????????? DatagramSocket send = new DatagramSocket();
?????????? DatagramSocket receive = new DatagramSocket(10001);
?????????? new Thread(new send(send)).start();
?????????? new Thread(new receive(receive)).start();
?????? } catch (SocketException e) {
?????????? e.printStackTrace();
?????? }
??? }
}
TCP:客户端服务端
?
Socket() 通过connect主动连接
?
Socket(InetAddress?address, int?port)
TCP传输的特点
分客户端和服务端
客户端对应的对象是socket,服务端对应的对象是serverSocket
通过查阅socket对象,发现该对象在建立时,可以去连接指定主机
因为TCP面向连接,所以在建立socket连接时,形成通路时,在通道进行传输
?
步骤
创建服务端
建立服务端的socket服务,serverSocket并监听一个端口
publicclass TCPTest01 {
??? publicstaticvoid? main(String[] args) throws IOException {
?????? Socket s = new Socket("192.168.1.255",10033);
?????? OutputStream out = s.getOutputStream();
?????? out.write("额三大".getBytes());
??? }
}
class TCPServer{
??? publicstaticvoid main(String[] args) throws IOException {
?????? //建立服务,监听端口
?????? ServerSocket s = new ServerSocket(10033);
?????? //通过accept方法获取对象
?????? Socket ss = s.accept();
?????? //获取客户端发送的数据,使用客户端对象来读取数据
?????? InputStream in = ss.getInputStream();
?????? byte[] b = newbyte[1024];
?????? int i = in.read(b);
?????? System.out.println(new String(b,0,i));
?????? System.out.println(ss.getInetAddress().getLocalHost());
?????? s.close();//服务端可以不关客户端必须关
??? }
}
?
?
浏览器访问服务端
ServerSocket ss = new ServerSocket(11232);
?????? Socket s = ss.accept();
?????? System.out.println(s.getInetAddress().getHostAddress());
?????? PrintWriter p = new PrintWriter(s.getOutputStream(),true);
?????? p.println("<p>aaa<p>");
?????? s.close();
?????? ss.close();
urlconnection
??? publicstaticvoid main(String[] args) throws IOException {
??? URL u = new URL("http://localhost:8080/myweb.html");
??? System.out.println(u.openConnection());
??? InputStream in = u.openConnection().getInputStream();
??? byte[] b? = newbyte[1024];
??? int a ;
??? while((a = in.read(b))!= -1)
??? {
?????? System.out.println(new String(b,0,a));
??? }
??? in.close();
?