网络
1.Java与网络
* 网络是java取得成功的领域之一
* (其他语言)数页代码---->(Java)一条语句
* 在java中有一个用来存储 internet 地址的类 InetAddress
例子://获取本机IP地址,创建 InetAddress 不用 new
import java.net.*;
public class GetLocalHost{
public static void main(String args[]){
InetAddress myIP=null;
try{
myIP=InetAddress.getLocalHost();
System.out.println(myIP);
}catch(Exception e){
e.printStackTrace();
}
}
}
* java提供的网络功能有3大类:
a. URL
通过URL可以直接送出或读入网络上的数据
b. socket
传统网络程序的最常用方式,可以想象为两个程序通过网络的通信信道
c. Datagram
更低级的网络传输方式,他把数据的目的地记录在数据包中,直接放在网上
2. OSI 模型和 TCP/IP 协议栈
* OSI 模型从下到上依次为:
(1)物理层 规定电气特性
(2)数据链路层 保证相临两台计算机传输,用物理地址(网卡地址 )做网络标识,主要设备 hub
(3)网络层 实现跨网段传输,用 IP 做标识,主要设备 router, 协议 IP
(4)传输层 保证无差错传输,协议 TCP,每个包都有syn号和效验码,传输前后的效验码比较,相同为正确,不同为错误,重传
这一层承上启下,出现了端口概念:用来区分不同的应用,范围 0--65535,0--1024一般不要用,是系统保留号
(5)会话层 如身份验证
(6)表现层
(7)应用层 Http,Ftp......
* TCP/IP 协议栈把OSI 模型合为四层
(1)链路层(物理层,数据链路层)
(2)网络层 IP,ICMP,ARP,RARP...
(3)传输层 TCP,UDP...
(4)应用层 (会话层,表现层,应用层) HTTP,FTP,TELNET,POP3,SMPT...
3.Socket
* Socket 是网络上运行的程序之间双向通信连路的最后终结点
* IP 与 端口 的组合得出一个套接字,可以完全分辨internet上的程序
* 端口号:TCP/IP 为每种程序定义了一个端口号,当一台计算机上运行不同程序时,根据端口号不同提供响应服务
端口号不是计算机上的物理连接器,只是具有软件意义的假想端口
* 常用端口号:
ftp: 21 http: 80 telnet: 23 nntp: 119 dns: 53 pop3: 110
* 在服务器端通过指定一个用来等待连接的端口号创建 ServerSocket 实例
* 在客户端通过规定一个主机和端口号创建 Socket 实例,连接到服务器
* 写一个 SocketServer 的步骤:
(1)创建一个ServerSocket对象
(2)调用 accept(),从客户端接受一个连接请求并返回一个新 socket
accept()是个阻塞方法,使 Server 启动,等待请求,开始监听
(3)从接受的socket中得到输入/输出流
(4)根据数据类型封装高级流(可选)
(5)收发信息
(6)释放资源
* 写一个 socket 客户端的步骤:
(1)创建一个 socket,向 Server发请求得到一个连接
(2)得到输入/输出流
(3)根据数据类型封装高级流(可选)
(4)收发信息
(5)释放资源
例子:
//server 读取 client 发来的数据显示出来,直到收到 "bye" 结束
//先打开一个命令行窗口运行 Server,然后再开一个运行 Client
import java.io.*;
import java.net.*;
public class Server{
public static void main(String args[]){
ServerSocket ss=null;
Socket s=null;
BufferedReader br=null;
String read=null;
try{
ss=new ServerSocket(1111);
System.out.println("Server is listening on 1111......");
s=ss.accept();
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
read=br.readLine();
System.out.println("read=>"+read);
if(read.equals("bye")) break;
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(br!=null) br.close();
if(s!=null) s.close();
if(ss!=null) ss.close();
System.out.println("Connection is closed");
}catch(Exception e){
e.printStackTrace();
}
}
}
//client 接收客户输入向server 发出,直到用户输入 "bye" 结束
import java.io.*;
import java.net.*;
public class Server{
public static void main(String args[]){
ServerSocket ss=null;
Socket s=null;
BufferedReader br=null;
String read=null;
try{
ss=new ServerSocket(1111);
System.out.println("Server is listening on 1111......");
s=ss.accept();
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
read=br.readLine();
System.out.println("read=>"+read);
if(read.equals("bye")) break;
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(br!=null) br.close();
if(s!=null) s.close();
if(ss!=null) ss.close();
System.out.println("Connection is closed");
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
* 上面的例子 client 一结束 server 也结束了,这太不实际了,下面做一个可以处理多用户的 server
这就需要多线程,server接到一个用户的请求就创建一个线程处理他
例子:
//多线程处理多请求,多开几个窗口试一下
import java.io.*;
import java.net.*;
public class Server{
public static void main(String args[]){
ServerSocket ss=null;
Socket s=null;
BufferedReader br=null;
String read=null;
try{
ss=new ServerSocket(1111);
System.out.println("Server is listening on 1111......");
//br=new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
s=ss.accept();
Thread t=new NewServer(s);
t.start();
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(br!=null) br.close();
if(s!=null) s.close();
if(ss!=null) ss.close();
System.out.println("Connection is closed");
}catch(Exception e){
e.printStackTrace();
}
}
}
}
class NewServer extends Thread{
BufferedReader br=null;
String read=null;
Socket s=null;
public NewServer(Socket s){
this.s=s;
}
public void run(){
try{
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
read=br.readLine();
System.out.println(getName()+" read=>"+read);
if(read.equals("bye")) break;
}
System.out.println(getName() +" connection is closed");
}catch(Exception e){
e.printStackTrace();
}finally{
if(br!=null) try{ br.close();} catch(Exception e){ e.printStackTrace(); }
if(s!=null) try{ s.close(); } catch(Exception e){ e.printStackTrace(); }
}
}
}
* 下面来做一个双向交互的例子,简单的用户名验证,接受用户输入的用户名,直到输入“java"为止
例子:
import java.io.*;
import java.net.*;
public class LoginServer{
public static void main(String[] args){
ServerSocket ss=null;
Socket s=null;
BufferedReader br=null;
PrintWriter pw=null;
String line=null;
String username="java";
try{
ss=new ServerSocket(1111);
System.out.println("Server is listening on 1111......");
s=ss.accept();
pw=new PrintWriter(
new OutputStreamWriter(s.getOutputStream()));
br=new BufferedReader(
new InputStreamReader(s.getInputStream()));
while(true){
pw.println("login:");
pw.flush();
line=br.readLine();
System.out.println(line);
if(line.equals(username)) {
pw.println("login sucessful");
pw.flush();
break;
}
pw.println("wrong name");
pw.flush();
line=null;
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(pw!=null) try{ pw.close(); }catch(Exception e){ e.getMessage(); }
if(br!=null) try{ br.close(); } catch(Exception e){ e.getMessage(); }
if(s!=null) try{ s.close(); } catch(Exception e){ e.getMessage(); }
if(ss!=null) try{ ss.close(); } catch(Exception e){ e.getMessage(); }
}
}
}
import java.io.*;
import java.net.*;
public class LoginClient{
public static void main(String[] args){
Socket s=null;
BufferedReader br=null,input;
PrintWriter pw=null;
String line=null;
String r=null,t=null;
try{
s=new Socket("127.0.0.1",1111);
br=new BufferedReader(
new InputStreamReader(s.getInputStream()));
input=new BufferedReader(
new InputStreamReader(System.in));
pw=new PrintWriter(
new OutputStreamWriter(s.getOutputStream()));
while(true){
line= br.readLine();
System.out.print(line);
r=input.readLine();
pw.println(r);
pw.flush();
t=br.readLine();
System.out.println(t);
if(t.equals("login sucessful")) break;
line=null;
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(pw!=null) try{ pw.close(); } catch(Exception e){ e.printStackTrace(); }
if(br!=null) try{ br.close(); } catch(Exception e) { e.printStackTrace(); }
if(s!=null) try{ s.close(); } catch(Exception e){ e.getMessage(); }
}
}
}
4. UDP
* UDP 为无连接协议,不可靠传输。DatagramSocket 和 DatagramPacket 支持 Java UDP
* 数据报是一个网络上发送的单独信息,他到达的时间和内容不能得到保证
* TCP 提供高可靠服务,适用于一次传送交换大量报文 的情况,信道上包不需要源地址和目的地址
UDP提供高效率服务,适用于依次传输交换少量报文的情况,每个包要包含目的地址和端口号
* 数据报文的使用以包为中心:打包,拆包
* 写 UDP Server 的步骤:
(1)创建一个绑定端口的 datagram DatagramSocket(port)
(2)准备一个DatagramPacket接受客户端的信息 DatagramPacket(buffer,len)
(3)从DatagramSocket接收信息放入 DatagramPacket
(4)读取信息
* 写 UDP Client 的步骤:
(1)创建一个 datagram socket DatagramSocket()
(2)准备一个包含信息和服务器协议地址信息的datagram packet DatagramPacket(buffer,len,Serveraddr,serverport)
(3)从datagram socket 把datagram packet发送到server
例子:
import java.net.*;
public class UDPServer{
public static void main(String[] args){
DatagramSocket ds=null;
DatagramPacket dp=null;
byte buf[]=new byte[1024];
try{
ds=new DatagramSocket(1111);
dp=new DatagramPacket(buf,buf.length);
System.out.println("begin recieve......");
ds.receive(dp);
String s=new String(dp.getData(),0,dp.getLength());
System.out.println("read=>"+s);
System.out.println("address:"+dp.getAddress());
System.out.println("socket address:"+dp.getSocketAddress());
System.out.println("port:"+dp.getPort());
}catch(Exception e){
e.printStackTrace();
}finally{
if( ds != null ) try{ ds.close(); } catch( Exception e ){}
}
}
}
import java.net.*;
public class UdpC{
public static void main(String[] args){
DatagramSocket ds=null;
DatagramPacket dp=null;
byte buf[]="hello world".getBytes();
try{
ds=new DatagramSocket();
dp=new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),1111);
ds.send(dp);
}catch(Exception e){
e.printStackTrace();
}finally{
if(ds!=null) try{ ds.close(); }catch(Exception e){ e.printStackTrace(); }
}
}
}
5.小结
* 网络上的数据传输是将网络连接转换成输入输出流
* Socket适用于面向连接的,高可靠的应用
* Socket是由IP和端口构成的一种网上通信连路的一端
* UDP适用效率高的应用
* Socket server/client 的编程步骤
* UDP server/client 的编程步骤
* 网络是java取得成功的领域之一
* (其他语言)数页代码---->(Java)一条语句
* 在java中有一个用来存储 internet 地址的类 InetAddress
例子://获取本机IP地址,创建 InetAddress 不用 new
import java.net.*;
public class GetLocalHost{
public static void main(String args[]){
InetAddress myIP=null;
try{
myIP=InetAddress.getLocalHost();
System.out.println(myIP);
}catch(Exception e){
e.printStackTrace();
}
}
}
* java提供的网络功能有3大类:
a. URL
通过URL可以直接送出或读入网络上的数据
b. socket
传统网络程序的最常用方式,可以想象为两个程序通过网络的通信信道
c. Datagram
更低级的网络传输方式,他把数据的目的地记录在数据包中,直接放在网上
2. OSI 模型和 TCP/IP 协议栈
* OSI 模型从下到上依次为:
(1)物理层 规定电气特性
(2)数据链路层 保证相临两台计算机传输,用物理地址(网卡地址 )做网络标识,主要设备 hub
(3)网络层 实现跨网段传输,用 IP 做标识,主要设备 router, 协议 IP
(4)传输层 保证无差错传输,协议 TCP,每个包都有syn号和效验码,传输前后的效验码比较,相同为正确,不同为错误,重传
这一层承上启下,出现了端口概念:用来区分不同的应用,范围 0--65535,0--1024一般不要用,是系统保留号
(5)会话层 如身份验证
(6)表现层
(7)应用层 Http,Ftp......
* TCP/IP 协议栈把OSI 模型合为四层
(1)链路层(物理层,数据链路层)
(2)网络层 IP,ICMP,ARP,RARP...
(3)传输层 TCP,UDP...
(4)应用层 (会话层,表现层,应用层) HTTP,FTP,TELNET,POP3,SMPT...
3.Socket
* Socket 是网络上运行的程序之间双向通信连路的最后终结点
* IP 与 端口 的组合得出一个套接字,可以完全分辨internet上的程序
* 端口号:TCP/IP 为每种程序定义了一个端口号,当一台计算机上运行不同程序时,根据端口号不同提供响应服务
端口号不是计算机上的物理连接器,只是具有软件意义的假想端口
* 常用端口号:
ftp: 21 http: 80 telnet: 23 nntp: 119 dns: 53 pop3: 110
* 在服务器端通过指定一个用来等待连接的端口号创建 ServerSocket 实例
* 在客户端通过规定一个主机和端口号创建 Socket 实例,连接到服务器
* 写一个 SocketServer 的步骤:
(1)创建一个ServerSocket对象
(2)调用 accept(),从客户端接受一个连接请求并返回一个新 socket
accept()是个阻塞方法,使 Server 启动,等待请求,开始监听
(3)从接受的socket中得到输入/输出流
(4)根据数据类型封装高级流(可选)
(5)收发信息
(6)释放资源
* 写一个 socket 客户端的步骤:
(1)创建一个 socket,向 Server发请求得到一个连接
(2)得到输入/输出流
(3)根据数据类型封装高级流(可选)
(4)收发信息
(5)释放资源
例子:
//server 读取 client 发来的数据显示出来,直到收到 "bye" 结束
//先打开一个命令行窗口运行 Server,然后再开一个运行 Client
import java.io.*;
import java.net.*;
public class Server{
public static void main(String args[]){
ServerSocket ss=null;
Socket s=null;
BufferedReader br=null;
String read=null;
try{
ss=new ServerSocket(1111);
System.out.println("Server is listening on 1111......");
s=ss.accept();
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
read=br.readLine();
System.out.println("read=>"+read);
if(read.equals("bye")) break;
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(br!=null) br.close();
if(s!=null) s.close();
if(ss!=null) ss.close();
System.out.println("Connection is closed");
}catch(Exception e){
e.printStackTrace();
}
}
}
//client 接收客户输入向server 发出,直到用户输入 "bye" 结束
import java.io.*;
import java.net.*;
public class Server{
public static void main(String args[]){
ServerSocket ss=null;
Socket s=null;
BufferedReader br=null;
String read=null;
try{
ss=new ServerSocket(1111);
System.out.println("Server is listening on 1111......");
s=ss.accept();
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
read=br.readLine();
System.out.println("read=>"+read);
if(read.equals("bye")) break;
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(br!=null) br.close();
if(s!=null) s.close();
if(ss!=null) ss.close();
System.out.println("Connection is closed");
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
* 上面的例子 client 一结束 server 也结束了,这太不实际了,下面做一个可以处理多用户的 server
这就需要多线程,server接到一个用户的请求就创建一个线程处理他
例子:
//多线程处理多请求,多开几个窗口试一下
import java.io.*;
import java.net.*;
public class Server{
public static void main(String args[]){
ServerSocket ss=null;
Socket s=null;
BufferedReader br=null;
String read=null;
try{
ss=new ServerSocket(1111);
System.out.println("Server is listening on 1111......");
//br=new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
s=ss.accept();
Thread t=new NewServer(s);
t.start();
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(br!=null) br.close();
if(s!=null) s.close();
if(ss!=null) ss.close();
System.out.println("Connection is closed");
}catch(Exception e){
e.printStackTrace();
}
}
}
}
class NewServer extends Thread{
BufferedReader br=null;
String read=null;
Socket s=null;
public NewServer(Socket s){
this.s=s;
}
public void run(){
try{
br=new BufferedReader(new InputStreamReader(s.getInputStream()));
while(true){
read=br.readLine();
System.out.println(getName()+" read=>"+read);
if(read.equals("bye")) break;
}
System.out.println(getName() +" connection is closed");
}catch(Exception e){
e.printStackTrace();
}finally{
if(br!=null) try{ br.close();} catch(Exception e){ e.printStackTrace(); }
if(s!=null) try{ s.close(); } catch(Exception e){ e.printStackTrace(); }
}
}
}
* 下面来做一个双向交互的例子,简单的用户名验证,接受用户输入的用户名,直到输入“java"为止
例子:
import java.io.*;
import java.net.*;
public class LoginServer{
public static void main(String[] args){
ServerSocket ss=null;
Socket s=null;
BufferedReader br=null;
PrintWriter pw=null;
String line=null;
String username="java";
try{
ss=new ServerSocket(1111);
System.out.println("Server is listening on 1111......");
s=ss.accept();
pw=new PrintWriter(
new OutputStreamWriter(s.getOutputStream()));
br=new BufferedReader(
new InputStreamReader(s.getInputStream()));
while(true){
pw.println("login:");
pw.flush();
line=br.readLine();
System.out.println(line);
if(line.equals(username)) {
pw.println("login sucessful");
pw.flush();
break;
}
pw.println("wrong name");
pw.flush();
line=null;
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(pw!=null) try{ pw.close(); }catch(Exception e){ e.getMessage(); }
if(br!=null) try{ br.close(); } catch(Exception e){ e.getMessage(); }
if(s!=null) try{ s.close(); } catch(Exception e){ e.getMessage(); }
if(ss!=null) try{ ss.close(); } catch(Exception e){ e.getMessage(); }
}
}
}
import java.io.*;
import java.net.*;
public class LoginClient{
public static void main(String[] args){
Socket s=null;
BufferedReader br=null,input;
PrintWriter pw=null;
String line=null;
String r=null,t=null;
try{
s=new Socket("127.0.0.1",1111);
br=new BufferedReader(
new InputStreamReader(s.getInputStream()));
input=new BufferedReader(
new InputStreamReader(System.in));
pw=new PrintWriter(
new OutputStreamWriter(s.getOutputStream()));
while(true){
line= br.readLine();
System.out.print(line);
r=input.readLine();
pw.println(r);
pw.flush();
t=br.readLine();
System.out.println(t);
if(t.equals("login sucessful")) break;
line=null;
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(pw!=null) try{ pw.close(); } catch(Exception e){ e.printStackTrace(); }
if(br!=null) try{ br.close(); } catch(Exception e) { e.printStackTrace(); }
if(s!=null) try{ s.close(); } catch(Exception e){ e.getMessage(); }
}
}
}
4. UDP
* UDP 为无连接协议,不可靠传输。DatagramSocket 和 DatagramPacket 支持 Java UDP
* 数据报是一个网络上发送的单独信息,他到达的时间和内容不能得到保证
* TCP 提供高可靠服务,适用于一次传送交换大量报文 的情况,信道上包不需要源地址和目的地址
UDP提供高效率服务,适用于依次传输交换少量报文的情况,每个包要包含目的地址和端口号
* 数据报文的使用以包为中心:打包,拆包
* 写 UDP Server 的步骤:
(1)创建一个绑定端口的 datagram DatagramSocket(port)
(2)准备一个DatagramPacket接受客户端的信息 DatagramPacket(buffer,len)
(3)从DatagramSocket接收信息放入 DatagramPacket
(4)读取信息
* 写 UDP Client 的步骤:
(1)创建一个 datagram socket DatagramSocket()
(2)准备一个包含信息和服务器协议地址信息的datagram packet DatagramPacket(buffer,len,Serveraddr,serverport)
(3)从datagram socket 把datagram packet发送到server
例子:
import java.net.*;
public class UDPServer{
public static void main(String[] args){
DatagramSocket ds=null;
DatagramPacket dp=null;
byte buf[]=new byte[1024];
try{
ds=new DatagramSocket(1111);
dp=new DatagramPacket(buf,buf.length);
System.out.println("begin recieve......");
ds.receive(dp);
String s=new String(dp.getData(),0,dp.getLength());
System.out.println("read=>"+s);
System.out.println("address:"+dp.getAddress());
System.out.println("socket address:"+dp.getSocketAddress());
System.out.println("port:"+dp.getPort());
}catch(Exception e){
e.printStackTrace();
}finally{
if( ds != null ) try{ ds.close(); } catch( Exception e ){}
}
}
}
import java.net.*;
public class UdpC{
public static void main(String[] args){
DatagramSocket ds=null;
DatagramPacket dp=null;
byte buf[]="hello world".getBytes();
try{
ds=new DatagramSocket();
dp=new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),1111);
ds.send(dp);
}catch(Exception e){
e.printStackTrace();
}finally{
if(ds!=null) try{ ds.close(); }catch(Exception e){ e.printStackTrace(); }
}
}
}
5.小结
* 网络上的数据传输是将网络连接转换成输入输出流
* Socket适用于面向连接的,高可靠的应用
* Socket是由IP和端口构成的一种网上通信连路的一端
* UDP适用效率高的应用
* Socket server/client 的编程步骤
* UDP server/client 的编程步骤
irini
2005-12-11 23:14:46
评论:0
阅读:336
引用:0
