您的位置:首页 > 理论基础 > 计算机网络

黑马程序员——网络编程

2015-09-20 22:17 603 查看

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

网络编程

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

建立连接采用的3次握手协议,具体是指:
第一次握手是客户端connect连接到server,server
accept client的请求之后,向client端发送一个消息,相当于说我都准备好了,你连接上我了,这是第二次握手,第3次握手就是client向server发送的,就是对第二次握手消息的确认。

之后client和server就开始通讯了。

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

网络编程概述



TCP和UDp特点:

UDP特点:
将数据及源和目的封装成数据包中,不需要建立连接。
每个数据报的大小在限制64k内。
因无连接,是不可靠协议。
不需要建立连接,速度快。

TCP特点:
建立连接,形成传输数据的通道。
在连接中进行大数据量的传输。
通过三次握手完成连接,是可靠协议。
必须建立连接,效率会稍低。

Socket
Socket就是为网络服务提供的一种机制。
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。

UDP传输
DatagramSocket与DatagramPacket。
建立发送端,接收端。
建立数据包。
调用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传输。
Socket和ServerSocket
建立客户端和服务器端。
建立连接后,通过Socket中的IO流进行数据的传输。
关闭Socket。
同样,客户端与服务器端是两个独立的应用程序。

练习:演示Tcp传输。
思路:
1、Tcp分客户端和服务端。
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、获取连接过来的客户端对象。

通过ServerSocket的accept方法。没有连接就是等。所以这个方法是阻塞式的。
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。

域名解析图例:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: