Java基础 网络编程 Socket UDP TCP URL
2015-07-02 18:59
836 查看
网络编程
网络模型OSI参考模型
TCP/IP参考模型
网络通讯要素
IP地址
端口号
传输协议
网络通讯要素
网络中设备的标识不易记忆,可用主机名
本地回环地址: 127.0.0.1 主机名: localhost
端口号
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024系统使用或保留端口
传输协议
通讯的规则
常见协议:TCP,UDP
TCP和UDP
UDP将数据及源和目的封装成数据包中,不需要建立连接
每个数据报的大小限制在64K内
因无连接,是不可靠协议
不需要建立连接,速度快
TCP
建立连接,形成传输数据的通道
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
Socket
Socket就是为网络服务提供的一种机制通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
UDP 发送接收
UDP发送端
import java.net.*; class UdpDemo { public static void main(String[] args) throws Exception { String data="hello"; //确定数据,并封装成数据包 byte[] b=data.getBytes(); InetAddress ia=InetAddress.getByName("192.168.0.104"); //1.创建UDP服务,通过DatagramSocket对象 DatagramSocket ds=new DatagramSocket(); //封装成数据包 DatagramPacket dp=new DatagramPacket(b,b.length,ia,10000); //通过socket服务,将已有的数据包发送出去通过send方法 ds.send(dp); //关闭资源 ds.close(); } }
UDP接收端
import java.net.*; class UdpReceive { public static void main(String[] args) throws Exception { byte[] b=new byte[1024]; DatagramSocket ds=new DatagramSocket(10000); DatagramPacket dp=new DatagramPacket(b,1024); ds.receive(dp); System.out.println(dp.getAddress().getHostAddress()); System.out.println(dp.getPort()); System.out.println(new String(dp.getData(),0,dp.getLength())); ds.close(); } }
重复接收,通过键盘输入发送数据
发送端import java.net.*; import java.io.*; class UdpSender { public static void main(String[] args) throws Exception { String data=""; //确定数据,并封装成数据包 InetAddress ia=InetAddress.getByName("192.168.0.104"); //1.创建UDP服务,通过DatagramSocket对象 DatagramSocket ds=new DatagramSocket(); //通过socket服务,将已有的数据包发送出去通过send方法 BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); while(true) { data=bufr.readLine() //封装成数据包 byte[] buf=data.getBytes(); DatagramPacket dp=new DatagramPacket(buf,buf.length,ia,10000); ds.send(dp); if(data.equals("bye")) break; } //关闭资源 ds.close(); } }
接收端
import java.net.*; class UdpReceive { public static void main(String[] args) throws Exception { byte[] buf=new byte[1024]; String senderAddress=""; String data=""; int senderPort=0; int dataLength=0; DatagramSocket ds=new DatagramSocket(10000); DatagramPacket dp=new DatagramPacket(buf,1024); while(true) { ds.receive(dp); senderAddress=dp.getAddress().getHostAddress(); senderPort=dp.getPort(); dataLength=dp.getLength(); data=new String(dp.getData(),0,dataLength); System.out.println(senderAddress+":"+senderPort+" "+data); if(data.equals("bye")) break; } ds.close(); } }
UDP 实现聊天
创建一个客户端,一个服务端分别绑定到10000和20000端口
创建两个线程
1个接收线程
通过提供的Socket和绑定的端口监听消息,并显示
1个发送线程
通过提供的Socket和绑定的端口发送消息到包 DatagramPacket 指定的地址和端口
UDP聊天程序1
import java.net.*; import java.io.*; //接受消息线程 class RecRun implements Runnable { DatagramSocket ds; String data; RecRun(DatagramSocket ds) { this.ds=ds; } public void run() { while(true) { try { byte[] bufr=new byte[1024]; DatagramPacket dp=new DatagramPacket(bufr,bufr.length); ds.receive(dp); data=new String(dp.getData(),0,dp.getLength()); System.out.println(""); System.out.println(dp.getAddress().getHostAddress()+":"+dp.getPort()+" 说:"); System.out.println(data); System.out.println(""); if(data.equals("bye")) { System.out.println("对方结束了通话,回车退出."); break; } } catch(Exception e) { //e.printStackTrace(); break; } } ds.close(); } } //发送消息线程 class SendRun implements Runnable { DatagramSocket ds; DatagramPacket dp; String line; SendRun(DatagramSocket ds,DatagramPacket dp) { this.ds=ds; this.dp=dp; } public void run() { BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); while(true) { try { System.out.println("请输入:"); line=bufr.readLine(); dp.setData(line.getBytes()); ds.send(dp); } catch(Exception e) { break; } if(line.equals("bye")) break; } ds.close(); } } class ChatServer { public static void main(String[] args) throws Exception { //创建发送目的包 int port=20000; byte[] buf=new byte[1024]; InetAddress ia=InetAddress.getByName("192.168.0.104"); DatagramPacket dp=new DatagramPacket(buf,buf.length,ia,port); //创建套接字,绑定本地端口号 DatagramSocket ds=new DatagramSocket(10000); //接收包 //创建接收消息线程,根据绑定的端口号进行监听 Thread recThread=new Thread(new RecRun(ds)); //创建发送消息线程,通过绑定的端口进行发送,发送到DatagramPacket 中 InetAddress 的IP地址和port端口号提供的接收地址. Thread sendThread=new Thread(new SendRun(ds,dp)); recThread.start(); sendThread.start(); } }
UDP聊天程序2
import java.net.*; import java.io.*; class ChatClient { public static void main(String[] args) throws Exception { byte[] bufs=new byte[1024]; //发送到的端口 int port=10000; //发送到的地址 InetAddress ia=InetAddress.getByName("192.168.0.104"); //套接字 DatagramSocket ds=new DatagramSocket(20000); DatagramPacket dps=new DatagramPacket(bufs,bufs.length,ia,port);; Thread recThread=new Thread(new RecRun(ds)); Thread sendThread=new Thread(new SendRun(ds,dps)); recThread.start(); sendThread.start(); } }
TCP
tcp分客户端和服务端客户端对应的对象是Socket
服务端对应的对象是ServerSocket
客户端
通过查阅Socket对象,发现在该对象建立时,就可以去连接指定主机
因为tcp是面向连接的,所以在建立socket服务时,就要有服务端存在,并连接成功,形成通路后,在该通道进行数据传输。
TCP服务端
import java.net.*; import java.io.*; class TcpServer { public static void main(String[] args) throws Exception { //创建一个服务端socket,绑定本机端口20000 ServerSocket mySocket=new ServerSocket(20000); //通过accept方法获取连接过来的客户端对象 Socket cSocket=mySocket.accept(); //获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据 String ip=cSocket.getInetAddress().getHostAddress(); System.out.println(ip+"已连接"); InputStream in=cSocket.getInputStream(); byte[] buf=new byte[1024]; int len=in.read(buf); String data=new String(buf,0,len); System.out.println(data); //关闭客户端 cSocket.close(); mySocket.close(); } }
TCP客户端
import java.net.*; import java.io.*; class TcpClient { public static void main(String[] args) throws Exception { //创建客户端的socket服务,指定目的主机和端口 Socket cSocket=new Socket("192.168.0.104",20000); OutputStream out=cSocket.getOutputStream(); BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); String str=bufr.readLine(); out.write(str.getBytes()); cSocket.close(); } }
TCP阻塞式聊天
1.服务器启动,等待客户端连接2.客户端连接,然后等待用户输入
3.用户输入信息,回车发送,客户端进入等待,等待服务器发送信息
4.服务器接受消息,并显示
5.服务器进入阻塞状态,等待用户输入信息
6.服务器发送信息给客户端
7.服务器进入等待,客户端收到信息并显示.
import java.io.*; import java.net.*; class TcpChatServer { public static void main(String[] args) throws Exception { ServerSocket sSocket=new ServerSocket(20000); Socket cSocket=sSocket.accept(); String ip=cSocket.getInetAddress().getHostAddress(); System.out.println(ip+"已连接"); //键盘输入流 BufferedReader kBufR= new BufferedReader(new InputStreamReader(System.in)); //网络输入流 BufferedReader bufR= new BufferedReader(new InputStreamReader(cSocket.getInputStream())); //网络输出流 BufferedWriter bufW= new BufferedWriter(new OutputStreamWriter(cSocket.getOutputStream())); String line; String lineInput; while((line=bufR.readLine())!=null) { if(line.equals("over")) break; System.out.println(ip+": "+line); lineInput=kBufR.readLine(); bufW.write(lineInput); bufW.newLine(); bufW.flush(); } kBufR.close(); cSocket.close(); sSocket.close(); } } class TcpChatClient { public static void main(String[] args) throws Exception { Socket cSocket=new Socket("192.168.0.104",20000); //键盘输入流 BufferedReader kBufR= new BufferedReader(new InputStreamReader(System.in)); //网络输入流 BufferedReader bufR= new BufferedReader(new InputStreamReader(cSocket.getInputStream())); //网络输出流 BufferedWriter bufW= new BufferedWriter(new OutputStreamWriter(cSocket.getOutputStream())); String line; String data; while((line=kBufR.readLine())!=null) { if(line.equals("over")) break; bufW.write(line); bufW.newLine(); bufW.flush(); data=bufR.readLine(); System.out.println("服务器说:"+data); } kBufR.close(); cSocket.close(); } }
URL
URL(String spec)根据 String 表示形式创建 URL 对象。
String getFile()
获取此 URL 的文件名。
String getHost()
获取此 URL 的主机名(如果适用)。
String getPath()
获取此 URL 的路径部分。
int getPort()
获取此 URL 的端口号。
String getProtocol()
获取此 URL 的协议名称。
String getQuery()
获取此 URL 的查询部分。
URLConnection openConnection()
返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。
URLConnection
直接已知子类:HttpURLConnection, JarURLConnection
InputStream getInputStream()
返回从此打开的连接读取的输入流。
OutputStream getOutputStream()
返回写入到此连接的输出流。
通过流对象可以像socket一样进行http通讯
通过getInputStream获取输入流可以从服务器获得网页源文件
相关文章推荐
- TCP常见问题FAQ
- juno dashboard创建网络,ping 通百度
- 网络请求2种方法
- Indy TIdTCPClient伪非阻塞式的解决方案
- 【Web探索之旅】第二部分第二课:服务器语言
- 【Web探索之旅】第一部分:什么是Web?
- 如何获取手机上网时的外部网络的IP地址
- Android三种基本的加载网络图片方式
- 统计内网机器网络流量的方案
- HTTP认证方式
- TCP closing a connection
- TCP Three-Way handshake
- http与WebSocket
- Win8笔记本一玩网络游戏就很卡不流畅的解决方法
- 虚拟机3种网络模式(桥接、nat、Host-only)
- 此地址使用了一个通常用于网络浏览以外的端口。出于安全原因,Firefox 取消了该请求。
- ios相关网络知识
- TCP/IP 问答
- CentOS下安装实时检测网络带宽的小工具bmon
- CentOS下安装实时检测网络带宽的小工具bmon