Java入门系列-24-实现网络通信
互联网上那么多设备,java 是如何与其他设备通信的呢?这次的内容是网络通信的基础,有了它咱们才能上网页、玩游戏、视频聊天。
Socket 客户端套接字
Socket 客户端套接字,用于连接互联网提供服务的设备。
Socket 构造方法
构造方法 | 说明 |
---|---|
Socket() | 通过系统默认类型的 SocketImpl 创建未连接套接字 |
Socket(String host, int port) | 创建一个流套接字并将其连接到指定主机上的指定端口号 |
常用方法
方法名称 | 说明 |
---|---|
getOutputStream() | 返回此套接字的输出流 |
getInputStream() | 返回此套接字的输入流 |
下面示例模拟了一个 HTTP 请求
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;public class TestSocket {public static void main(String[] args) {//创建套接字try(Socket s=new Socket("www.baidu.com", 80);){//创建向服务器发送数据的输出流OutputStream os=s.getOutputStream();StringBuffer sb=new StringBuffer();//HTTP协议 请求报文sb.append("GET / HTTP/1.1\r\n");sb.append("Host: www.baidu.com:80\r\n");sb.append("Connection: Keep-Alive\r\n");//这里一定要一个回车换行,表示消息头完,不然服务器会等待sb.append("\r\n");//发送os.write(sb.toString().getBytes());//获取服务器相应内容 InputStream is=s.getInputStream();//通过输入流创建扫描器,并指定编码为utf-8防止中文乱码Scanner scanner=new Scanner(is,"utf-8");while(scanner.hasNextLine()) {String line=scanner.nextLine();System.out.println(line);}} catch (UnknownHostException e) {e.printStackTrace();System.out.println("未知主机");} catch (IOException e) {e.printStackTrace();System.out.println("IO异常");}}
}
ServerSocket
ServerSocket:实现服务器套接字,服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;public class TestServerSocket {public static void main(String[] args) {//创建 ServerSocket 监听1666端口try(ServerSocket server=new ServerSocket(1666)){//阻塞方法,当有客户端连入,获取客户端Sockettry(Socket client=server.accept()){//获取客户端发送的数据InputStream is=client.getInputStream();//获取向客户端发送数据的流OutputStream os=client.getOutputStream();//通过输入流创建扫描器try(Scanner scanner=new Scanner(is)){PrintWriter pw=new PrintWriter(os,true/*自动刷新*/);//向客户端发送消息pw.println("Hello,enter bye to exit.");boolean done=false;//客户端有输入数据并且没有发送 bye while(!done&&scanner.hasNextLine()) {//接收客户端发送的数据String line=scanner.nextLine();//将客户端发送的数据发回客户端pw.println("Echo:"+line);//如果客户端输入bye 结束通信if(line.trim().equalsIgnoreCase("bye")) {done=true;}}}}} catch (IOException e) {e.printStackTrace();}}
}
测试方式:
在DOS 中输入命令:telnet 127.0.0.1 1666
telnet 不是内部或外部命令的读者,需要在 Windows 功能中启用 Telnet 客户端。
上面的代码如果有多个客户端连入就不行了,如果希望服务能被多个客户端连接,可以使用线程。
多线程服务器
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;public class TestMultiServerSocket {public static void main(String[] args) {//创建 ServerSocket 监听 1666端口try(ServerSocket server=new ServerSocket(1666)){while(true) {//accept() 是一个阻塞方法Socket client=server.accept();InputStream is=client.getInputStream();OutputStream os=client.getOutputStream();//开启新的线程处理,传入当前客户端Thread t=new Thread(new ThreadEchoHandler(client));t.start(); }} catch (IOException e) {e.printStackTrace();}}
}
class ThreadEchoHandler implements Runnable{private Socket socket=null;public ThreadEchoHandler(Socket socket) {this.socket=socket;}@Overridepublic void run() {try {InputStream is=socket.getInputStream();OutputStream os=socket.getOutputStream();try(Scanner scanner=new Scanner(is)){PrintWriter pw=new PrintWriter(os,true);pw.println("Hello,enter bye to exit.");boolean done=false;while(!done&&scanner.hasNextLine()) {String line=scanner.nextLine();pw.println("Echo:"+line);if(line.trim().equalsIgnoreCase("bye")) {done=true;}}}socket.close();} catch (IOException e) {e.printStackTrace();}}}
URLConnection
抽象类 URLConnection 是所有类的超类,它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。
Socket 可以默认任意类型的网络通信,URLConnection 更适合 HTTP 请求,使用 URLConnection 进行HTTP操作更方便,模拟请求报文,获取响应报文和内容。
URLConnection 常用方法
方法 | 说明 |
---|---|
connect() | 打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接) |
getContentEncoding() | 返回 content-encoding 头字段的值 |
getContentType() | 返回 content-type 头字段的值 |
getHeaderFields() | 返回头字段的不可修改的 Map |
getInputStream() | 返回从此打开的连接读取的输入流 |
setRequestProperty(String key, String value) | 设置一般请求属性 |
获取 URLConnection 需要先创建 URL 对象:
URL url=new URL(host);
使用 URLConnection 获取网页的内容
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;public class TestURLConnection {public static void main(String[] args) {try {//创建URL对象URL url=new URL("http://www.baidu.com");//创建 URLConnection对象URLConnection connection=url.openConnection();//设置请求属性//connection.setRequestProperty("", "");//连接connection.connect();//获取输入流InputStream is=connection.getInputStream();//通过输入流构建一个扫描器Scanner scanner=new Scanner(is,"utf-8");while(scanner.hasNextLine()) {String line=scanner.nextLine();System.out.println(line);}System.out.println("===响应头===");Map<String,List<String>> headers=connection.getHeaderFields();for (Entry<String, List<String>> entry: headers.entrySet()) {String key=entry.getKey();System.out.print(key+":");for (String string : entry.getValue()) {System.out.print(string);}System.out.println();}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}
Java入门系列-24-实现网络通信相关推荐
- SAP PM入门系列24 - IK07 Display Measuring Points
SAP PM入门系列24 - IK07 Display Measuring Points SAP PM的基础报表里,对于计量点(Measuring Points)这个技术对象,也提供了标准的查询报表. ...
- go io.reader 多次读取_Go 经典入门系列 24:Select
点击上方蓝色"Go语言中文网"关注,每天一起学 Go 欢迎来到 Golang 系列教程[1]的第 24 篇. 什么是 select? select 语句用于在多个发送/接收信道操作 ...
- Java入门系列-26-JDBC
认识 JDBC JDBC (Java DataBase Connectivity) 是 Java 数据库连接技术的简称,用于连接常用数据库. Sun 公司提供了 JDBC API ,供程序员调用接口和 ...
- Java入门系列——Java语言基础(小康小白)
我是小康小白,一个平平无奇的Java,Python小白.热爱有趣的文字,生活和远方. 个人博客:https://blog.csdn.net/weixin_45791445 有问题欢迎QQ联系:1059 ...
- Java入门系列-16-继承
这一篇文章教给新手学会使用继承,及理解继承的概念.掌握访问修饰符.掌握 final 关键字的用法. 继承 为什么要使用继承 首先我们先看一下这两个类: public class Teacher {pr ...
- Java入门系列-09-循环结构
这篇文章为你搞懂5个问题 while 循环如何使用 do-while 循环的使用 for 循环的使用 break.continue 的使用 循环结构的嵌套使用 生活中有很多事情需要我们重复的去做,比如 ...
- Java入门系列-11-类和对象
这篇文章为你搞懂类和对象的使用 对象:用来描述客观事物的实体,由一组属性和方法组成,万物皆对象. 属性:就是对象的特征,像身高.体重.颜色 方法:对象的行为,如跑.跳 类:类是模子,定义对象将会拥有的 ...
- Java入门系列-22-IO流
File类的使用 Java程序如何访问文件?通过 java.io.File 类 使用File类需要先创建文件对象 File file=new File(String pathname);,创建时在构造 ...
- Java入门系列-20-异常
为什么要进行异常处理 下面这段代码能否正常执行 public class DemoCalc {public static void main(String[] args) {int a=0;int b ...
最新文章
- 比特币和以太坊本质有什么区别?
- PageOffice实现js执行在线编辑时Word文档中的宏命令
- 硕士:论文提交和考试
- javascript时间戳和日期字符串相互转换代码
- (回溯 UVa129)困难的串
- Pytest脚本中运行用例方式
- 对称机密算法与非对称机密算法
- jQuery源码研究分析学习笔记-jQuery.fn.init()(五)
- 超图Cesium量算
- A - Giga Tower
- C语言typedef:给类型起一个别名
- MySQL · 引擎介绍 · Sphinx源码剖析(二)
- 概率论中的矩母函数(MGF)
- iOS开发中的Web应用概述
- 等额本息贷款与等额本金贷款比较
- Python课程第十一天_下午_课程笔记(包和模块)
- thinkphp配置文件设置session有效期未生效的问题
- Android webview 自动登陆新浪微博实现(原理)
- HC-SR04超声波模块传感器
- MySQL到底大小写敏感还是不敏感?