失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 黑马程序员 java基础之网络编程TCP

黑马程序员 java基础之网络编程TCP

时间:2022-05-24 03:27:08

相关推荐

黑马程序员 java基础之网络编程TCP

TCP网络传输。

客户端和服务端

分别对应着两个对象。

Scoket(客户端)和ServerSocket(服务端)。

Socket(String address, int port)

创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

这个客户端在一建立的情况下就去连接服务端。

通过指定地址和指定的端口找到服务端。并与之建立连接。

步骤:

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

Socket s = new Socket("localhost",10002);

如果上述这步成功了的话。也就是通路建立了。

当通路一建立,就有一个Socket流,也就是网络流。

两端之间建立了一个网络流。Socket中既有输入流也有输出流,

一旦建立连接,在Socket中就可以取到输入流和输出流对数据进行操作。

流不用去建立,只要通路一建立,流就存在了。

getOutputStream()

返回此套接字的输出流。

getInputStream()

返回此套接字的输入流。

服务端

服务端没有自己的流对象。

服务端和客户端连接的时候,就使用了客户端的流对象和客户端进行操作。

public classTCPSocket {

/**

*@param args

*/

public static void main(String[] args)throws Exception

{

Socket s = newSocket("localhost",10002);

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

OutputStream os =s.getOutputStream();

BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(os));

bw.write("tcp,gemenwolaile");

bw.flush();

//而在这里不同去关流

s.close();

}

}

/*

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

* 服务端:

* 1.建立服务端的Socket服务。通过ServerSocket类去建立。

* 一旦建立,并监听一个端口。

* 2.获取链接过来的客户端对象。

* 通过ServerSocket的accept方法去获得。所以这个方法是阻塞式。

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

* 的读取流来读取发过来的数据。并打印在控制台。

* 4.关闭服务端。(可选)

*

* */

class TcpServer

{

public static void main(String[] args)throws Exception

{

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

ServerSocket ss = new ServerSocket(10002);

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

Socket s = ss.accept();

System.out.println(s.getInetAddress().getHostAddress());

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

InputStream in = s.getInputStream();

byte[] buf = new byte[1024];

int len = in.read(buf);

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

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

}

}

必须先启动服务端。

演示tcp传输的客户端和服务端的互访。

需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。

/*

1.建立socket服务。指定要连接的主机和端口

2.获取socket流中的输出流,将数据写到该流中。通过网络发送给服务端。

3.获取socket流中的输入流,将服务器反馈的数据获取到,并打印。

4.关闭客户端资源。

*/

class TcpClient2

{

public static void main(String[] args)throws Exception

{

Socket s = new Socket("localhost",10004);

OutputStream os = s.getOutputStream();

os.write("nihao".getBytes());

InputStream is = s.getInputStream();

byte [] arr = new byte[1024];

//十分要主要,这里的read读的是Socket流。也是一个阻塞式方法。只有服务端往回发送数据的时候,才会解除阻塞。

int len = is.read(arr);

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

s.close();

}

}

class TcpServer2

{

public static void main(String[] args)throws Exception

{

ServerSocket ss = newServerSocket(10004);

Socket s = ss.accept();

InputStream is = s.getInputStream();

byte [] arr = new byte[1024];

int len = is.read(arr);

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

OutputStream os =s.getOutputStream();

os.write("完成".getBytes());

s.close();

}

}

package day5;

.*;

importjava.io.*;

public classTCPSocket2 {

public static void main(String[] args) {

// TODO Auto-generated method stub

}

}

class Client3

{

public static void main(String[] args)throws Exception

{

Socket s = newSocket("localhost",10009);

BufferedWriter bw = new BufferedWriter(newOutputStreamWriter(s.getOutputStream()));

BufferedReader br = newBufferedReader(new InputStreamReader(System.in));

String ss = null;

BufferedReader brr = newBufferedReader(new InputStreamReader(s.getInputStream()));

while((ss = br.readLine())!=null)

{

bw.write(ss);

bw.newLine();

bw.flush();

System.out.println(brr.readLine());

}

br.close();

s.close();

}

}

class Server3

{

public static void main(String[] args)throws Exception

{

ServerSocket ss = newServerSocket(10009);

Socket s = ss.accept();

InputStream is = s.getInputStream();

BufferedReader br = newBufferedReader(new InputStreamReader(is));

OutputStream os =s.getOutputStream();

BufferedWriter bw = new BufferedWriter(newOutputStreamWriter(os));

String sss = null;

while((sss = br.readLine())!=null)

{

//上边的readLine只有在看到回车符后才能结束,也就是解除阻塞。

bw.write(sss.toUpperCase());

bw.newLine();

bw.flush();

}

//有一个疑问,为什么当客户端结束的时候,服务端也结束了,

//这是因为,当客户端调用s.close()时,会在流里写一个-1,

//然后服务器端就跳出循环,然后通过ss关闭服务器。

ss.close();

}

}

要注意,对于读取流中的阻塞式方法来说,一定要将发送发的缓冲区刷新。

而且必须将行结束符写到这个流中。

对于服务器端的阻塞式方法,如readLine(),必须在客户端发送一个标志,让服务器端知道其结束了,否则服务器一直处于读取数据的状态。

在客户端使用

s.shutdownOutput();//关闭客户端的输出流,相当于给流中加入一个结束标记

下边,我们使用更高级的协议去完成一个自定义浏览器和tomcat服务器的处理请求。

可以直接使用应用层的协议去封装。

URL url = newURL("http://localhost:8080/GP2/index.jsp");

//首先将url地址封装到一个对象为URL中。

URLConnectionconn = url.openConnection();

//这个URLConnection就封装了有关底层协议的一些信息。

//也就通过一些应用层的协议进行拆包,并将这些属性封装到这个对象中去.

//然后通过openConnection()在内部帮助我们去完成Socket等一系列连接动作。

//所以不同写Socket(是在传输层上的协议),而且是带着协议去封装的。

//当连接成功,当然可以将其服务端传递过来的数据拿到。也就是得到输入流对象。

从获取值

InputStream is =conn.getInputStream();

//从而从这个流对象中的得到值

byte [] arr =new byte[1024];

int len = 0;

while((len = is.read(arr))!=-1)

{

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

}

这时候传递过来的数据就没有了响应头。而直接打出html中的信息。

这是因为。当底层的网络协议把数据封装好之后(包括响应头),通过应用层去拆包之后,将数据和响应头分离开来,得到的数据就只剩数据了。

而这些响应头中的信息,可以通过URLConnection对象中的一系列方法进行简析.

比如说:System.out.println(conn.getHeaderField("Server"));

可以得到有关服务器的信息。

当浏览器写入一个网址之后,去访问某一台主机的时候.它到底做什么了事情?

在上网的时候,先去本地找hosts中的各自域名的映射关系.

当本地有,就返回本地的,如localhost,如果本地没有,就去各自运营商提供的域名服务器DNS中去寻找映射关系,最后使用ip地址找到对应的服务器,使用端口找到对应的应用程序.如果直接输入ip地址,则不走域名简析.

如果觉得《黑马程序员 java基础之网络编程TCP》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。