------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
网络编程:
网络编程是什么?
网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机。数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一个设备反馈的数据。现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈。在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)。客户端程序可以在需要的时候启动,而服务器为了能够时刻相应连接,则需要一直启动。
网络编程参考模型:
网络通讯三要素:
IP地址:InterAdress
网络中设备的识别。
不易记,可用主机名。
本地回环地址:127.0.0.1,本地主机名:localhost
端口号;
用于表示进程的逻辑地址,不同进程的标识。
有效端口:0~65535.其中0~1024为系统保留端口。
传输协议。
通讯的规则。
常见协议:TCP,UDP
TCP和UDP
UDP:
1,将数据及源和目的封装成数据包,不需要建立连接。
2,在连接中进行大数据量传输。
3,因为无连接,是不可靠协议。
4,不需要建立连接速度快。
(对讲机)
TCP:
, 1,建立连接,形成传输数据的通道。
2,在连接中进行大数据传输。
3,通过三次握手完成连接,是可靠协议。
4,必须建立连接,效率稍低。
(打电话)
InetAddress:
此类表示互联网协议 (IP) 地址。
InetAddress类常用方法:
InetAddress:构造方法私有,不能直接创建对象。
getAddress
()
返回此 InetAddress
对象的原始 IP 地址
getAllByName
(
String
host)
在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组
getByName
(
String
host)
在给定主机名的情况下确定主机的 IP 地址。
getHostAddress
()
返回 IP 地址字符串(以文本表现形式)。
getHostName
()
获取此 IP 地址的主机名。
getLocalHost
()
返回本地主机。
toString
()
将此 IP 地址转换为 String
。
getAllByName
(
String
host)
在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。
示例:
package com.itheima;
import java.net.InetAddress;
public class InetAddressDemo {
public static void main(String[] args) throws Exception {
//获取本地主机。
InetAddress i = InetAddress.getLocalHost();
System.out.println(i);
//通过名称获取主机地址
i = InetAddress.getByName("www.sina.com");
System.out.println(i);
//通过名称获取所有主机地址
InetAddress[] allIt = InetAddress.getAllByName("www.baidu.com");
for (InetAddress inetAddress : allIt) {
System.out.println(inetAddress);
}
//返回当前地址,文本形式
System.out.println(i.getHostAddress());
//返回当前地址名称
System.out.println(i.getHostName());
}
}
Socket
Socket就是为网络服务的一种机制。
通信的两端都有Socket
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。
TCP传输:
在TCP中有两个端口:客户端,服务端。
客户端对应的对象为:Socket
服务端对应的对象为:ServerSocket
TCP客户端建立:
1:建立tcp的socket服务,最好明确具体的地址和端口。这个对象在创建时,就已经可以对指定ip和端口进行连接(三次握手)。
2:如果连接成功,就意味着通道建立了,socket流就已经产生了。只要获取到socket流中的读取流和写入流即可,只要通过getInputStream和getOutputStream就可以获取3:两个流对象。
4:关闭资源。
package com.itheima;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TCPSocket {
public static void main(String[] args) throws Exception {
String ip = InetAddress.getLocalHost().getHostAddress();
Socket s = new Socket(ip, 10000);
OutputStream out = s.getOutputStream();
out.write("Hellow".getBytes());
s.close();
}
}
TCP服务端建立:
1,建立服务端的socket服务,ServerSocket();
并监听一个端口。
2,获取连接过来的客户端对象。
通过ServerSokcet的 accept方法。所以这个方法是阻塞式的。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端的读取流来读取发过来的数据。通过getInputStream和getOutputStream就可以获取两个流对象。
4,关闭服务端。
示例一:简单对话
package com.itheima;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 需求:定义端点接受数据并打印在控制台上。
*/
public class TCPServerSocket {
public static void main(String[] args) throws Exception {
//建立服务端的socket服务,并且监听一个端口。
ServerSocket ss = new ServerSocket(10000);
//通过accept方法获取链接过来的客户端对象。
Socket s = ss.accept();
//获得ip地址
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"...coming");
//获取客户端发送过来的数据,那么就要使用客户端的读取流来读数据。
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len));
s.close();
ss.close();
}
}
示例二:双向对话(转换客户端传入文字.)
客户端:
package com.itheima;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClient3 {
publicstatic void main(String[] args) throws Exception {
Stringstr = InetAddress.getLocalHost().getHostAddress();
Sockets = new Socket(str, 10002);
//定义读取键盘的流对象。
BufferedReaderbufr =
new BufferedReader(new InputStreamReader(System.in));
//定义目的,将数据写入到socket输出流。发给服务端.
BufferedWriterbufOut =
new BufferedWriter(newOutputStreamWriter(s.getOutputStream()));
//定义一个socket读取流,读取服务端返回的大写信息、
BufferedReaderbufIn =
new BufferedReader(newInputStreamReader(s.getInputStream()));
StringlineOut = null;
while((lineOut= bufr.readLine())!=null){
if("over".equals(lineOut))
break;
bufOut.write(lineOut);
bufOut.newLine();
bufOut.flush();
Stringstr1 = bufIn.readLine();
System.out.println(str1);
}
s.close();
}
}
服务端
package com.itheima;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer3 {
publicstatic void main(String[] args) throws Exception{
ServerSocketss = new ServerSocket(10002);
Sockets = ss.accept();
System.out.println(s.getInetAddress().getHostAddress());
//读取socket读取流中的数据。
BufferedReaderbufIn =
new BufferedReader(newInputStreamReader(s.getInputStream()));
//目的:socket输出流,将大写数据写入到socket输出流并发送给客户端。
BufferedWriterbufOut =
new BufferedWriter(newOutputStreamWriter(s.getOutputStream()));
Stringline = null;
while((line=bufIn.readLine())!=null){
bufOut.write(line.toUpperCase());
bufOut.newLine();
bufOut.flush();
}
s.close();
ss.close();
}
}
在上面示例中,传输的都是文本数据所以可以用Read加入缓冲技术,注意添加newLine(),因为没有结束标记,而双方有阻塞式方法。
示例三:TCP协议传输图片。
客户端:
package com.itheima;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TcpCopyPicClient {
public static void main(String[] args) throws Exception {
String ip = InetAddress.getLocalHost().getHostAddress();
Socket s = new Socket(ip,10002);
InputStream in = new FileInputStream("c:\\1.jpg");
OutputStream out = s.getOutputStream();
byte[] buf= new byte[1024];
int len = 0;
while((len = in.read(buf))!=-1){
out.write(buf, 0, len);
}
s.shutdownOutput();
BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line =null;
while((line = bufr.readLine())!=null){
System.out.println(line);
}
}
}
服务端:
package com.itheima;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpCopyPicServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10002);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress());
InputStream in = s.getInputStream();
OutputStream out = new FileOutputStream("1.jpg");
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1){
out.write(buf, 0, len);
}
pw.println("上传成功");
out.close();
in.close();
s.close();
}
}
需求:通过udp传输方式将一段文字数据发送出去。
思路:
1,建立udpsocket服务。
2,提供数据,并将数据封装到数据包中。
3,通过socket服务的发送功能将数据包发送出去。
4,关闭资源。
示例:
(UDP不需要建立连接,发送小数据)
package com.itheima;
import java.net.DatagramSocket;
public class UdpTalk {
public static void main(String[] args) throws Exception {
DatagramSocket sendDs = new DatagramSocket();
DatagramSocket receDs = new DatagramSocket(10005);
new Thread(new Send(sendDs)).start();
new Thread(new Rece(receDs)).start();
}
}
package com.itheima;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Send implements Runnable {
private DatagramSocket ds;
public Send(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
// TODO Auto-generatedmethod stub
try {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=bufr.readLine())!=null){
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(),10005);
ds.send(dp);
}
} catch (IOException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
package com.itheima;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Rece implements Runnable {
private DatagramSocket ds;
public Rece(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
// TODO Auto-generatedmethod stub
try {
while (true) {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 0, buf.length);
ds.receive(dp);
System.out.println(dp.getAddress().getHostAddress());
System.out.println(new String(dp.getData(), 0, dp.getLength()));
}
} catch (IOException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}