Java——网络编程
2015-08-18 15:07
519 查看
网络编程
在网络中发送数据分几个步骤:
1、首先要找到对方IP
2、要发到指定的应用程序上 就要对应用程序进行数字标识,这些标识叫做端口
3、定义通讯规则,称为协议,国际通用协议是TCP/IP协议,但不是唯一协议
所以网络通讯要素有三:
1、IP地址
2、端口号
3、传输协议
网络模型:
OSI模型:
从上至下依次是:应用层 -> 表示层 -> 会话层 -> 传输层 -> 网络层 -> 数据链路层 -> 物理层
TCP/IP模型:
从上至下依次是:应用层 -> 传输层 -> 网际层 -> 主机至网络层
IP地址:
IP地址是网络中设备的标识
不易记忆,可用主机名
本地回路地址:127.0.0.1 主机名:localhost
对应的java类是InetAddress类
InetAddress类
没有构造函数,通过静态方法getLocalHost()方法获取本类对象。
常用方法:
getByname(String host) //通过IP地址或主机名获取主机
getHostAddress() //获取IP地址的字符串形式
getHostName() //获取主机名
示例:
UDP协议:
特点是:面向无连接,速度快,不可靠。
使用方法是通过DatagramSocket类建立对象,再使用DatagramPacket对象将要发送的数据封装进数据包对象,然后使用DatagramSocket对象的send()方法发送,
同时指定端口和目的主机。
下面是发送端和接收端的代码示例:
发送端:
buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, buf.length);//3、通过receive方法 将数据存入数据包中ds.receive(dp);//阻塞方法//4、通过数据包的方法 获取其中的数据String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(), 0, dp.getLength());int port =
dp.getPort();System.out.println(ip + "::" + data + "::" + port);}//5、关闭资源//ds.close();}}
练习:利用UDP协议实现聊天功能,一个程序同时进行收发操作,所以要利用多线程。
代码:
TCP协议:
特点:面向连接,通过三次握手确立连接,速度较慢,可靠性高。
使用Tcp协议,必须明确客户端和服务端,客户端使用Socket类,并在构造方法中指定目的主机地址和端口号。
服务器端使用ServerSocket类,并用accept()方法接受一个Socket对象,建立连接后,才可以传输数据。
常用方法有:
getInputStream() //获取Socket对象的输入流
getOutputStream() //获取Socket对象的输出流
示例:
练习:客户端接收键盘录入信息发送给服务端,服务端将其转成大写再反馈给客户端
代码:
模拟实际应用:上传图片:
客户端将本地图片发送给服务端,服务端反馈“接收成功”。
需要注意的是,服务端应能完成同时接收多个客户端同时上传的操作,所以每接收到一个客户端Socket,都将其封装成一个线程,才能实现同时接收。
代码如下:
实际应用2:实现多用户登陆功能。
建立一张用户名表,客户端接收键盘录入,发送给服务端,服务端查询用户名表,如果存在则返回登陆成功,否则返回失败,一个IP最多失败三次,然后禁止登陆。
代码:
自定义服务端,接收来自浏览器的请求并返回信息给浏览器。
代码:
URL
URL全称是uniform resource locator,中文是统一资源定位器,是资源的一种标识。
对应的类是URL。
常用方法:
构造函数:URL(String protocol,String host,int port,String file);//指定 protocol、host、port号和 file
String getProtocol() //获取协议名称
String getHost() //获取主机名
int getPort() //获取端口号
String getFile() //获取URL文件名
String getPath() //获取此URL的路径部分
String getQuery() //获取此URL的查询部,客户端传输的特定信息
示例:
域名解析:
在浏览器地址栏中输入一个域名时,浏览器会首先在本地host文件中查询对应的IP,如果存在则直接访问,如果不存在,就请求网络供应商,访问对方的DNS服务器。
DNS服务器中存储的是大量的IP和域名的映射表,再通过映射表找到对应IP,访问对应服务器。
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
在网络中发送数据分几个步骤:
1、首先要找到对方IP
2、要发到指定的应用程序上 就要对应用程序进行数字标识,这些标识叫做端口
3、定义通讯规则,称为协议,国际通用协议是TCP/IP协议,但不是唯一协议
所以网络通讯要素有三:
1、IP地址
2、端口号
3、传输协议
网络模型:
OSI模型:
从上至下依次是:应用层 -> 表示层 -> 会话层 -> 传输层 -> 网络层 -> 数据链路层 -> 物理层
TCP/IP模型:
从上至下依次是:应用层 -> 传输层 -> 网际层 -> 主机至网络层
IP地址:
IP地址是网络中设备的标识
不易记忆,可用主机名
本地回路地址:127.0.0.1 主机名:localhost
对应的java类是InetAddress类
InetAddress类
没有构造函数,通过静态方法getLocalHost()方法获取本类对象。
常用方法:
getByname(String host) //通过IP地址或主机名获取主机
getHostAddress() //获取IP地址的字符串形式
getHostName() //获取主机名
示例:
import java.net.*; class IPDemo { <span style="white-space:pre"> </span>public static void main(String[] args)throws UnknownHostException <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>InetAddress ip = InetAddress.getLocalHost(); <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>System.out.println(ip.toString()); <span style="white-space:pre"> </span>System.out.println(ip.getHostAddress()); <span style="white-space:pre"> </span>System.out.println(ip.getHostName()); <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>InetAddress ips[] = InetAddress.getAllByName("www.google.com"); <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>for(InetAddress i : ips) <span style="white-space:pre"> </span>System.out.println(i.getHostAddress()); <span style="white-space:pre"> </span>} }
UDP协议:
特点是:面向无连接,速度快,不可靠。
使用方法是通过DatagramSocket类建立对象,再使用DatagramPacket对象将要发送的数据封装进数据包对象,然后使用DatagramSocket对象的send()方法发送,
同时指定端口和目的主机。
下面是发送端和接收端的代码示例:
发送端:
import java.io.*; import java.net.*; class UdpSend { public static void main(String[] args)throws SocketException,UnknownHostException,IOException { //1、通过DatagramSocket对象 创建Udp对象 DatagramSocket ds = new DatagramSocket(); //2、确定数据 封装成数据包 DategramPacket(byte[] buf, int length, // InetAddress address, int port) BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line = bufr.readLine()) != null) { if(line.equals("88")) break; byte[] buf = line.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.103"), 12322); //3、通过socket服务 将已有数据包发送出去 通过send方法 ds.send(dp); } //4、关闭资源 ds.close(); } }接收端:
<pre name="code" class="html">import java.io.*; import java.net.*;class UdpRece{public static void main(String[] args)throws SocketException,UnknownHostException,IOException{DatagramSocket ds = new DatagramSocket(12322);while(true){//1、通过DatagramSocket对象 创建Udp对象//2、定义数据包 用于存储byte[]
buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, buf.length);//3、通过receive方法 将数据存入数据包中ds.receive(dp);//阻塞方法//4、通过数据包的方法 获取其中的数据String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(), 0, dp.getLength());int port =
dp.getPort();System.out.println(ip + "::" + data + "::" + port);}//5、关闭资源//ds.close();}}
练习:利用UDP协议实现聊天功能,一个程序同时进行收发操作,所以要利用多线程。
代码:
import java.net.*; import java.io.*; class ChatDemo { public static void main(String[] args)throws Exception { DatagramSocket sendSock = new DatagramSocket(); DatagramSocket receSock = new DatagramSocket(22233); new Thread(new Rece(receSock)).start(); new Thread(new Send(sendSock)).start(); } } class Send implements Runnable { private DatagramSocket ds; public Send(DatagramSocket ds) { this.ds = ds; } public void run() { try { BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line = bufr.readLine()) != null) { if(line.equals("end")) break; byte[] buf = line.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.255"), 11112 ); ds.send(dp); } ds.close(); }catch(Exception e) { throw new RuntimeException("send failed"); } } } class Rece implements Runnable { private DatagramSocket ds; public Rece(DatagramSocket ds) { this.ds = ds; } public void run() { try { while(true) { byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); String data = new String(dp.getData(), 0, dp.getLength()); String ip = dp.getAddress().getHostAddress(); System.out.println(data); } }catch(Exception e) { throw new RuntimeException("reveive failed"); } } }
TCP协议:
特点:面向连接,通过三次握手确立连接,速度较慢,可靠性高。
使用Tcp协议,必须明确客户端和服务端,客户端使用Socket类,并在构造方法中指定目的主机地址和端口号。
服务器端使用ServerSocket类,并用accept()方法接受一个Socket对象,建立连接后,才可以传输数据。
常用方法有:
getInputStream() //获取Socket对象的输入流
getOutputStream() //获取Socket对象的输出流
示例:
import java.io.*; import java.net.*; class TcpClient { public static void main(String[] args)throws Exception { //创建客户端Socket,指定目的主机 端口 Socket s = new Socket("169.254.90.177", 10003); //为了发送数据,应该获取Socket流中的输出流 OutputStream out = s.getOutputStream(); out.write("tcp data".getBytes()); s.close(); } } class TcpServer { public static void main(String[] args)throws Exception { //创建服务端Socket 绑定端口 ServerSocket ss = new ServerSocket(10003); //通过accept()方法获取连接过来的客户端流对象 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + " connected"); //获取客户端发来的数据,要使用客户端的读取流方法 来读取数据 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf, 0, len)); }
练习:客户端接收键盘录入信息发送给服务端,服务端将其转成大写再反馈给客户端
代码:
import java.io.*; import java.net.*; class TClient { public static void main(String[] args)throws Exception { //发送 Socket s = new Socket("169.254.90.177", 23333); OutputStream out = s.getOutputStream(); BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line = bufr.readLine()) != null) { if(line.equals("over")) break; out.write(line.getBytes()); //接收反馈 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String rData = new String(buf, 0, len); System.out.println(rData); } s.close(); } } class TServer { public static void main(String[] args)throws Exception { //接收 ServerSocket ss = new ServerSocket(23333); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + " connected"); InputStream in; OutputStream out; while(true) { in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String data = new String(buf, 0, len); if(data.equals("over")) break; //反馈 String rData = data.toUpperCase(); out = s.getOutputStream(); out.write(rData.getBytes()); } } }
模拟实际应用:上传图片:
客户端将本地图片发送给服务端,服务端反馈“接收成功”。
需要注意的是,服务端应能完成同时接收多个客户端同时上传的操作,所以每接收到一个客户端Socket,都将其封装成一个线程,才能实现同时接收。
代码如下:
import java.net.*; import java.io.*; class ThreadClient { public static void main(String[] args)throws Exception { if(args.length != 1) { System.out.println("wrong path"); return; } File file = new File(args[0]); if(! (file.exists() && file.isFile())) { System.out.println("wrong file"); return; } if(! file.getName().endsWith(".jpg")) { System.out.println("wrong file format"); return; } if(file.length() > 1024 * 1024 * 3) { System.out.println("file too large"); return; } Socket s = new Socket("169.254.90.177", 23335); FileInputStream fis = new FileInputStream(file); OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len = fis.read(buf)) != -1) { out.write(buf, 0, len); } s.shutdownOutput(); InputStream in = s.getInputStream(); byte[] bufIn = new byte[1024]; int lenIn = 0; lenIn = in.read(bufIn); System.out.println(new String(bufIn, 0, lenIn)); s.close(); } } class ThreadServer { public static void main(String[] args)throws Exception { ServerSocket ss = new ServerSocket(23335); while(true) { Socket s = ss.accept(); new Thread(new PicThread(s)).start(); } } } class PicThread implements Runnable { private Socket s; PicThread(Socket s) { this.s = s; } public void run() { String ip = s.getInetAddress().getHostAddress(); try { int count = 1; System.out.println(ip + " connected"); File file = new File(ip + "(" + count + ")" + ".jpg"); while(file.exists()) file = new File(ip + "(" + count++ + ")" + ".jpg"); InputStream in = s.getInputStream(); FileOutputStream fos = new FileOutputStream(file); byte[] buf = new byte[1024]; int len = 0; while((len = in.read(buf)) != -1) { fos.write(buf, 0, len); } OutputStream out = s.getOutputStream(); out.write("file received".getBytes()); } catch(Exception e) { throw new RuntimeException(ip +" upload failed"); } } }
实际应用2:实现多用户登陆功能。
建立一张用户名表,客户端接收键盘录入,发送给服务端,服务端查询用户名表,如果存在则返回登陆成功,否则返回失败,一个IP最多失败三次,然后禁止登陆。
代码:
import java.net.*; import java.io.*; class LoginClient { public static void main(String[] args)throws IOException { Socket s = new Socket("169.254.90.177", 23338); BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(s.getOutputStream(), true); BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null, info = null; for(int i = 0; i < 3; i++) { line = bufr.readLine(); if(line == null) break; out.println(line); info = bufIn.readLine(); System.out.println("info: " + info); if(info.contains("welcome")) break; } s.close(); bufr.close(); } } class UserThread implements Runnable { private Socket s; public UserThread(Socket s) { this.s = s; } public void run() { String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + ".. connected"); try { for(int i = 0; i < 3; i ++) { BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream())); String name = bufr.readLine(); if(name == null) break; BufferedReader bufIn = new BufferedReader(new FileReader("user.txt")); String line = null; PrintWriter out = new PrintWriter(s.getOutputStream(), true); boolean found = false; while((line = bufIn.readLine()) != null) { if(line.equals(name)) { found = true; break; } } if(found == true) { System.out.println(name + " login"); out.println("welcome " + name ); break; }else { System.out.println(name + " try to login"); out.println(name + " name not found"); } } s.close(); }catch(Exception e) { throw new RuntimeException(ip + " check failed"); } } } class LoginServer { public static void main(String[] args)throws IOException { ServerSocket ss = new ServerSocket(23338); while(true) { Socket s = ss.accept(); new Thread(new UserThread(s)).start(); } } }
自定义服务端,接收来自浏览器的请求并返回信息给浏览器。
代码:
import java.net.*; import java.io.*; class ServerDemo { public static void main(String[] args)throws IOException { ServerSocket ss = new ServerSocket(10086); Socket s = ss.accept(); System.out.println(s.getInetAddress().getHostAddress() + "..connected"); PrintWriter out = new PrintWriter(s.getOutputStream(), true); out.println("hello client"); } }
URL
URL全称是uniform resource locator,中文是统一资源定位器,是资源的一种标识。
对应的类是URL。
常用方法:
构造函数:URL(String protocol,String host,int port,String file);//指定 protocol、host、port号和 file
String getProtocol() //获取协议名称
String getHost() //获取主机名
int getPort() //获取端口号
String getFile() //获取URL文件名
String getPath() //获取此URL的路径部分
String getQuery() //获取此URL的查询部,客户端传输的特定信息
示例:
import java.net.*; import java.io.*; class URLDemo { public static void main(String[] args)throws MalformedURLException { URL url = new URL("http://169.254.90.177:8080/myweb/demo.html"); System.out.println("getProtocol()" + url.getProtocol()); System.out.println("getHost()" + url.getHost()); System.out.println("getPort()" + url.getPort()); System.out.println("getPath()" + url.getPath()); System.out.println("getFile()" + url.getFile()); System.out.println("getQuery()" + url.getQuery()); } }
域名解析:
在浏览器地址栏中输入一个域名时,浏览器会首先在本地host文件中查询对应的IP,如果存在则直接访问,如果不存在,就请求网络供应商,访问对方的DNS服务器。
DNS服务器中存储的是大量的IP和域名的映射表,再通过映射表找到对应IP,访问对应服务器。
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
相关文章推荐
- hdu 4278 2012天津赛区网络赛 数学 *
- VMware11 + centOs 7 安装及网络配置
- linux tcpdump命令详解
- 曾经的笔记迁移__通用链表网络版
- http响应码信息
- 打造安全的App!iOS安全系列之 HTTPS
- 【计算机网络】HTTP协议详解
- http://www.cocoachina.com/ios/20150812/12938.html
- java - (06) http
- http://www.cnblogs.com/kissazi2/p/4133927.html
- Android安卓根据地址下载文件并保存到本地(HttpDownload)
- Android 快速开发框架网络篇-Android-Async-Http
- HTTP 协议详解
- 国家自然科学基金重点项目启动暨软件定义网络 技术前瞻研讨会
- iOS应用架构谈 网络层设计方案
- HTTP 状态消息、code状态码查询
- 《从零开始学Swift》学习笔记http(Day1)——我的第一行Swift代码
- 数据中心网络虚拟化-隧道技术
- 基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类
- HTTP 报头字段 以及 返回值