一、网络通信的概述:
1、IP地址对应java中的一个类(InetAddress)。
(1)、创建了一个InetAddress类的对象就代表创建了一个IP地址。
InetAddress:位于java.net包下
1、InetAddress用来代表IP地址。一个InetAddress的对象就代表着一个IP地址。
2、如何创建InetAddress的对象:InetAddress.getByName(String host);:host可以是IP或者域名
获取本机IP:InetAddress.getLocalHost();
3、对象的方法:
(1)、getHostName():获取IP地址对应的域名
(2)、getHostAddress():获取IP地址
一个端口号对应机器的一个进程的运行。
package InetAddress;
import java.net.InetAddress;
import java.net.UnknownHostException;
/*
* InetAddress:位于java.net包下
* 1、InetAddress用来代表IP地址。一个InetAddress的对象就代表着一个IP地址。
* 2、如何创建InetAddress的对象:InetAddress.getByName(String host);:host可以是IP或者域名
* 获取本机IP:InetAddress.getLocalHost();
* 3、对象的方法:
* (1)、getHostName():获取IP地址对应的域名
* (2)、getHostAddress():获取IP地址
*
*
* */
public class TestInetAddress {
public static void main(String[] args) throws UnknownHostException {
InetAddress inet=InetAddress.getByName("www.baidu.com");//:通过域名访问
inet=InetAddress.getByName("39.156.66.18");//通过IP访问
System.out.println(inet);//结果:域名/IP
System.out.println(inet.getHostName());//getHostName():获取IP地址对应的域名
System.out.println(inet.getHostAddress());//getHostAddress():获取IP地址
System.out.println();
//访问本机
InetAddress inet1=InetAddress.getLocalHost();
System.out.println(inet1);
System.out.println(inet1.getHostName());
System.out.println(inet1.getHostAddress());
}
}
IP 域名 注:一个IP对应一个域名,二者是同一个物体的两个名字
(2)、端口号:
注:一个端口号对应机器的一个进程的运行。
二、网络通信协议(传输):
1、基于TCP_IP协议的网络编程:
端口号与IP地址的组合得出一个网络套接字(Socket)。
(1)、客户端给服务器端发送信息。服务端输出此信息到控制台上。
(2)、客户端的操作基本步骤:
-1、创建一个Socket对象,通过构造器指明服务器的IP地址,以及其接受程序的端口号
socket=new Socket(InetAddress.getByName("192.168.2.102"), 9090);//创建Socket,要知道对方的接口以及对方要接受的应用是哪一个。
-2、getOutputStream():发送数据,方法返回OutputStream的对象
os=socket.getOutputStream();//创建一个连接的对象
-3、具体的输出过程:调用write方法,把信息传出去
os.write("我是客户端,请多关照".getBytes());//调用write方法,把信息传出去
-4、关闭相应的流:输入或输出流--Socket流
(3)、服务端的操作基本步骤:
-1、创建ServerSocket的对象,通过ServerSocket构造器指明自身的端口号。
ss=new ServerSocket(9090);
-2、调用accept()方法返回一个Socket的对象
s=ss.accept();
-3、调用Socket对象的getInputStream()获取一个从客户端发送过来的输入流
is=s.getInputStream();
-4、对获取的流进行操作:输出到控制台或打印到文件中
byte[] b=new byte[20];
int len;
while((len=is.read(b))!=-1) {
String str=new String(b,0,len);
System.out.print(str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
-5、关闭资源:先关闭流InputStraem--Socket--ServerSocket
1、客户端与服务端交互代码实例1(含讲解):
package InetAddress;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import org.junit.Test;
/*
* TCP编程例一、客户端给服务器端发送信息。服务端输出此信息到控制台上。
* */
public class TestTCP1 {
//客户端(Socket)
//网络编程实际上就是Socket编程
@Test
public void client() { //再启动服务端
Socket socket=null;
OutputStream os=null;
try { // 对方的IP 端口号
//1、创建一个Socket对象,通过构造器指明服务器的IP地址,以及其接受程序的端口号
// // 对方的IP 端口号
socket=new Socket(InetAddress.getByName("192.168.2.102"), 9090);//1、创建Socket,要知道对方的接口以及对方要接受的应用是哪一个。
//2、getOutputStream():发送数据,方法返回OutputStream的对象
os=socket.getOutputStream();//创建一个连接的对象
//3、具体的输出过程
os.write("我是客户端,请多关照".getBytes());//调用write方法,把信息传出去
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//4、关闭相应的流:输入或输出流--Socket流
if(os!=null) {
try {
os.close();//关闭流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(socket!=null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//服务端(ServerSocket):接受
@Test
public void server() { //先启动服务端
ServerSocket ss=null;
Socket s=null;
InputStream is=null;
try {
//1、创建ServerSocket的对象,通过ServerSocket构造器指明自身的端口号。
ss=new ServerSocket(9090);
//2、调用accept()方法返回一个Socket的对象
s=ss.accept();
//3、调用Socket对象的getInputStream()获取一个从客户端发送过来的输入流
is=s.getInputStream();
//4、对获取的流进行操作:输出到控制台或打印到文件中
byte[] b=new byte[20];
int len;
while((len=is.read(b))!=-1) {
String str=new String(b,0,len);
System.out.print(str);
}
System.out.println("收到来自于"+s.getInetAddress().getHostAddress()+"的连接");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//5、关闭资源:先关闭流InputStraem--Socket--ServerSocket
finally {
if(is!=null) {//1、输入流
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(s!=null) {//2、Socket流
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ss!=null) {//ServerSocket流
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
运行时,两次单元测试:第一次先运行server;之后再运行client;最终会得到结果。如果先开客户端会有错,因为没有先打开服务端,连接无法启动。必须先打开服务端。
2、客户端与服务端交互代码实例2(含讲解):
有了InputStream后就一定要用字符数组或者字节数组接收,放到数组里。
且InputStream对应read;OutputStream对应write;
TCP编程例二、客户端给服务端发送信息,服务端将信息打印到控制台,同时发送"已收到信息"给客户端。
package InetAddress;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import org.junit.Test;
/*
* TCP编程例二、客户端给服务端发送信息,服务端将信息打印到控制台,同时发送"已收到信息"给客户端。
* */
public class TestTCP2 {
//客户端
@Test
public void client() {
Socket socket=null;
OutputStream os=null;
InputStream is=null;
try {
//发出去1
socket = new Socket(InetAddress.getByName("192.168.2.102"),8989);
os = socket.getOutputStream();
os.write("我是客户端".getBytes());
//shutdownOutput():执行此方法显式地告诉服务端执行完毕。
socket.shutdownOutput(); //如果客户端为服务端传递完了数据,就关闭此连接。
//接收来自服务端返回的提示信息。
is = socket.getInputStream();
byte[]b=new byte[20];
int len;
while((len=is.read(b))!=-1) {
String str=new String(b,0,len);
System.out.println(str);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(is!=null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(os!=null) {
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(socket!=null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//服务端
@Test
public void server() {
//接受1
ServerSocket ss=null;
Socket s=null;
InputStream is=null;
//发出去2
OutputStream os=null;
try {
ss = new ServerSocket(8989);
s = ss.accept();
is = s.getInputStream();
byte[] b=new byte[20];
int len;
while((len=is.read(b))!=-1) {
String str=new String(b,0,len);
System.out.println(str);
}
//给客户端提示一下自己已经收到传来的信息。
os = s.getOutputStream();
os.write("我已经收到你的情意".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(os!=null) {
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(is!=null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(s!=null) {
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ss!=null) {
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
3、基于TCP_IP协议的网络编程例三- - -浏览器访问Tomcat服务器端资源:
操作文件:
package InetAddress;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import org.junit.Test;
/*
* TCP编程例三、客户端发送文件给服务端,服务端保存到本地。并返回"发送成功"给客户端。并关闭相应的连接。
*如下的程序处理异常时必须使用try-catch
**/
public class TestTCP3 {
@Test
public void client() throws Exception{
//1、创建Socket的对象
Socket socket=new Socket(InetAddress.getByName("192.168.2.102"),9898);
//2、从本地获取一个文件发送给服务器
OutputStream os=socket.getOutputStream();
FileInputStream fis=new FileInputStream(new File("1.gif"));
byte[]b=new byte[1024];
int len;
while((len=fis.read(b))!=-1) {
os.write(b,0,len);
}
socket.shutdownOutput();//告诉目标我已经发送完毕
//3、接收来自于服务端的信息
InputStream is=socket.getInputStream();
byte[] b1=new byte[1024];
int len1;
while((len1=is.read(b1))!=-1) {
String str=new String(b1,0,len1);
System.out.println(str);
}
//4、关闭相应的流和Socket对象:从后往前看
is.close();
os.close();
fis.close();
socket.close();
}
@Test
public void server() throws Exception{
//1、创建ServerSocket的对象,需要指明端口号,这样才能找到你。
ServerSocket ss=new ServerSocket(9898);
//2、调用accept()的方法,返回一个Socket的对象
Socket s=ss.accept();
//3、将从客户端接收的信息保存到本地
InputStream is=s.getInputStream();
FileOutputStream fos=new FileOutputStream(new File("3.gif"));
byte[] b=new byte[1024];
int len;
while((len=is.read(b))!=-1) {
fos.write(b,0,len);
}
System.out.println("收到来自于"+s.getInetAddress().getHostAddress()+"的文件");
//4、发送"接受成功"的信息反馈给客户端
OutputStream os=s.getOutputStream();
os.write("你发送的图片我已接收成功!".getBytes());
//5、关闭相应的流(此处偷个懒,自己写必须用try-catch)
os.close();
fos.close();
is.close();
s.close();
ss.close();
}
}
彩蛋:
Tomcat服务器使用:(1)、在Tomcat的bin目录下找到start.bat点击启动tomcat ;
(2)、在tomcat的webapps目录下新建一个文件夹,文件夹里面新建hello.txt,在txt中输入一些内容;
(3)、打开浏览器输入http://192.168.2.102:8080/test.txt:数字部分是本地的IP,(也可以用别的电脑上的IP,这样访问别的电脑),这样就可以看到txt中的内容显示在tomcat服务器。
四、基于UDP_IP协议的网络编程:
效率比较高。
DatagramPack的常用方法:
byte[] | getData() 返回数据缓冲区。 |
int | getLength() 返回将要发送或接收到的数据的长度。 |
UDP_IP的编程:
package UDP_IP;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import org.junit.Test;
public class TestUDP {
//客户端
@Test
public void send() {
//TCP使用Socket,UDP使用DatagramSocket
DatagramSocket ds=null;
try {
ds = new DatagramSocket();
byte[] b="你好,我是要发送的数据".getBytes();
//不在Socket中指明往哪里发,而在数据报中指明往哪里发
//创建一个数据报:每一个数据报不能大于64k,都记录着数据信息,发送端的IP、端口号,以及要发送到的接收端的IP、端口号。
DatagramPacket pack=new DatagramPacket(b, 0,b.length,InetAddress.getByName("192.168.2.102"),9090);
ds.send(pack); //发送数据报
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(ds!=null) {
ds.close();
}
}
}
//接收端
@Test
public void receive() {
DatagramSocket ds=null;
try {
ds = new DatagramSocket(9090);
byte[] b=new byte[1024];
DatagramPacket pack=new DatagramPacket(b, 0,b.length); //数据报不需要IP和端口号了。
ds.receive(pack); //接受数据报
//输出
String str=new String(pack.getData(),0,pack.getLength());
System.out.println(str);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(ds!=null) {
ds.close();
}
}
}
}