黑马程序员——网络编程



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



网络编程 



TCP连接建立的时候3次握手,断开连接的4次握手的具体过程


建立连接采用的3次握手协议,具体是指:

第一次握手是客户端connect连接到serverserver accept client的请求之后,向client端发送一个消息,相当于说我都准备好了,你连接上我了,这是第二次握手,第3次握手就是clientserver发送的,就是对第二次握手消息的确认。
之后clientserver就开始通讯了。


断开连接的4次握手,具体如下:

断开连接的一端发送close请求是第一次握手,另外一端接收到断开连接的请求之后需要对close进行确认,发送一个消息,这是第二次握手,发送了确认消息之后还要向对端发送close消息,要关闭对对端的连接,这是第3次握手,而在最初发送断开连接的一端接收到消息之后,进入到一个很重要的状态time_wait状态,最后一次握手是最初发送断开连接的一端接收到消息之后。对消息的确认。 


网络编程概述 


TCPUDp特点:


UDP特点:

将数据及源和目的封装成数据包中,不需要建立连接。

每个数据报的大小在限制64k内。

因无连接,是不可靠协议。

不需要建立连接,速度快。 


TCP特点:

建立连接,形成传输数据的通道。

在连接中进行大数据量的传输。

通过三次握手完成连接,是可靠协议。

必须建立连接,效率会稍低。 


Socket

Socket就是为网络服务提供的一种机制。

通信的两端都有Socket

网络通信其实就是Socket间的通信。

数据在两个Socket间通过IO传输。 


UDP传输

DatagramSocketDatagramPacket

建立发送端,接收端。

建立数据包。

调用Socket的发送接收方法。

关闭Socket

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


例:

InetAddress i = InetAddress.getLocalHost();

System.out.println(i.toString());

System.out.println("adress:"+i.getHostAddress());

System.out.println("name:"+i.getHostName()); 


练习:

需求:通过UDP传输方式,将一段文字数据发送出去。

定义一个udp发送端。

思路:

1、建立udpsocket服务。

2、提供数据,并将数据封装到数据包中。

3、通过socket服务的发送功能,将数据包发出去。

4、关闭资源。

import java.net.*;

class UdpSend

{

                  publicstatic void main(String[] args) throws Exception

                  {

                     //1创建UDP服务,通过DatagramSocket对象。

                     DatagramSocketds = new DatagramSocket();

                     //2确定数据,并封装成数据包,DatagramPacket

                     byte[]buf = "udp ge men lai le".getBytes();

                     DatagramPacket dp = newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.104"),1000);

                     //3通过Scoket服务,将已有的数据包发送出去。通过send方法

                     ds.send(dp);

                     //4  关闭资源。

                     ds.close();

                  }

}



必要掌握一下。

编写一个聊天程序。

有收数据的部分,和发数据的部分。

这两部分需要同时执行。

那就需要用到多线程技术。

一个线程控制收,一个线程控制发。

因为收和发动作是不一致的,所以要定义两个run方法。

而且这两个方法要封装到不同的类中。


import java.net.*;

import java.io.*;

class Send implements Runnable

{

                  privateDatagramSocket ds;

   public Send(DatagramSocket ds)

                  {

                     this.ds= ds;

                  }

                  publicvoid run()

                  {

                     try

                     {

                            BufferedReaderbufr = new BufferedReader(new InputStreamReader(System.in));

                            Stringline = null;

                            while((line= bufr.readLine()) != null)

                            {

                                   if("886".equals(line))

                                          break;

                                   byte[]buf = line.getBytes();

                                   DatagramPacketdp = newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10002);

                                   ds.send(dp);

                            }

                     }

                     catch(Exception e)

                     {

                            thrownew RuntimeException("发送端失败。");

                     }

                  }

}

class Rece implements Runnable

{

     privateDatagramSocket ds;

   public Rece(DatagramSocket ds)

                  {

                     this.ds= ds;

                  }

                  publicvoid run()

                  {

                     try

                     {

                            while(true)

                            {

                                   byte[]buf = new byte[1024];

                                   DatagramPacketdp = new DatagramPacket(buf,buf.length);

                                   ds.receive(dp);

                                   Stringip = dp.getAddress().getHostAddress();

                                   Stringdata = new String(dp.getData(),0,dp.getLength());

                                   System.out.println(ip+"  "+data);

                            }

                     }

                     catch(Exception e)

                     {

                            thrownew RuntimeException("接收端失败。");

                     }

                  }

}

class ChatDemo

{

                  publicstatic void main(String[] args) throws Exception

                  {

                     DatagramSocketsendSocket = new DatagramSocket();

                     DatagramSocketreceSocket = new DatagramSocket(10003);         

                     newThread(new Send(sendSocket)).start();

                     newThread(new Rece(receSocket)).start();

                  }

}


 

Tcp传输图例:


 


 


TCP传输。

SocketServerSocket

建立客户端和服务器端。

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

关闭Socket

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


练习:演示Tcp传输。

思路:

1Tcp分客户端和服务端。

2、客户端对应的对象是Socket

       服务端对应的对象是ServerSocket

客户端:

通过查阅Scoket对象,发现在该对象建立时,就可以去连接指定主机。

因为Tcp是面向连接的,所以在建立Socket服务时,

就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输。

需求:

给服务端发送一个文本数据。

步骤:

1、创建Socket服务,并指定要连接的主机和端口。 

import java.io.*;

import java.net.*;

class TcpClient

{

                  publicstatic void main(String[] args) throws Exception

                  {

                     //创建客户端的Socket服务,指定目的主机和端口。

                     Sockets = new Socket("192.168.1.104",10004);

                     //为了发送数据,应该获取Socket流中的输出流。

                     OutputStreamout = s.getOutputStream();

                     out.write("tcpge men lai le".getBytes());

                     s.close();

                  }

} 


需求:定义端点接收数据并打印在控制台上

服务端:

1、建立服务端的Socket服务。ServerSocket();

                  并监听一个端口。

2、获取连接过来的客户端对象。

                  通过ServerSocketaccept方法。没有连接就是等。所以这个方法是阻塞式的。

3、客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。

                  并打印在控制台。

4、关闭服务端。(可选)

class TcpServer

{

                  publicstatic void main(String[] args) throws Exception

                  {

                     //建立服务端的Socket服务,并监听一个端口。

                     ServerSocketss = new ServerSocket(10004);

                     //通过accept方法获取连接过来的客户端对象。

                     Sockets = ss.accept();

                     Stringip = s.getInetAddress().getHostAddress();

                     System.out.println(ip+"----connected");

                     //获取客户端发送过来的数据,那么要使用客户端对象的读取流方法来读取数据。

                     InputStreamin = s.getInputStream();

                     byte[]buf = new byte[1024];

                     intlen = in.read(buf);

                     System.out.println(newString(buf,0,len));

                     s.close();//关闭客户端。

                     ss.close();//可选

                  }

}

服务端

这个服务端有个局限性,当A客户端连接上以后,被服务端获取到,服务端执行具体流程。

这是B客户端连接,只有等待。

因为服务端还没有处理完A客户端的请求,还循环回来执行下次accept方法。所以暂时获取不到B客户端对象。

那么为了可以让多个客户端同时并发访问服务端。

那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。


如何定义线程呢?

只要明确了每一个客户端要在服务端执行的代码,将该代码存入run方法中。 


自定义浏览器——Tomcat服务端图例:



 




URL对象


URL常用方法:

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

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

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

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

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

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


会出现这个异常:MalformedURLException


装包拆包图例:



 

URLConnection必须掌握。


import java.io.*;

import java.net.*;

class URLConnectionDemo

{

                  publicstatic void main(String[] args) throws Exception

                  {

                     URLurl = newURL(http://192.168.1.102/myweb/demo.html?name=haha&&age=10);

                     URLConnectionconn = url.openConnection();

                     System.out.println(conn);

                     InputStreamin = conn.getInputStream();

                     byte[]buf = new byte[1024];

                     intlen = in.read(buf);

                     System.out.println(newString(buf,0,len));

                  }

}

 


域名解析:


想要将主机名翻译成IP地址,需要域名解析DNS


域名解析图例:



 


 


 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值