您的位置:首页 > 理论基础 > 计算机网络

java 网络编程

2017-04-21 10:22 309 查看

1. 网络模型:

OSI参考模型:(应用层,表示层,会话层,传输层,网络层,数据链路层,物理层)

TCP/IP参考模型:(应用层,传输层,网际层,主机至网络层)

2. 网络通讯要素

IP地址

本地回环地址:127.0.0.1,主机名:localhost

端口

可用端口:0~65535,其中0~1024是系统使用或者保留端口。

3. Java网络编程常见对象

3.1 根据主机名获取IP地址

//通过主机名获取对应的IP地址
static void netAddressTest1() throws UnknownHostException{
InetAddress inetAddress=InetAddress.getByName("www.baidu.com");
System.out.println("ip地址是"+inetAddress.getHostAddress());
}


4. UDP和TCP的特点

4.1 UDP

将数据及源和目的封装成数据包,不许要建立连接。

每个数据包的大小限制在64K内。

因无连接,是不可靠协议。

不需要建立连接,速度快。

4.2 TCP

建立连接,形成传输数据的通道。

在连接中进行大数据量传输。

通过三次握手完成连接,是可靠协议。

必须建立连接,效率会稍低。

- 5. UDP的发送和接收

UDP的发送和接收涉及到两个类:DatagramSocket,DatagramPacket。

DatagramSocket是一个Socket,发送方可以指定数据发出去时的端口,也可以不指定,会自动分配。接收方的DatagramSocket需要指定那个端口用来接收数据。(目的和源端口必须一致)

DatagramPacket是数据的载体。发送方的DatagramPacket在创建时需要明确接收方的IP地址和端口。

5.1 简单发送

指明接收方的IP和端口,本机用来发送数据的端口,可指定也可不指定。

将发送的数据填充到byte[]数组里面,然后用该数组构建一个DatagramPacket对象。

代码:

static void udpSend1() throws Exception{
String hostName="127.0.0.1";
//创建DatagramSocket对象
DatagramSocket datagramSocket=new DatagramSocket();
byte[]datas="haha".getBytes();
//构建DatagramPacket类,其封装了要发送的数据和目的地信息
DatagramPacket datagramPacket=new DatagramPacket(datas, datas.length,InetAddress.getByName(hostName),9999);
//发送
datagramSocket.send(datagramPacket);

//关闭资源
datagramSocket.close();
}


5.2 简单接收

创建DatagramSocket对象时,必须明确那个端口用来接收数据。

创建一个空的字节数组用来接受数据,根据此字节数组创建DatagramPacket对象。

DatagramSocket的receive()方法是阻塞式的。

代码:

static void udpReceive()throws Exception{
//创建Socket,并且必须指明那个端口用来接收消息
DatagramSocket socket=new DatagramSocket(9999);
//创建字节数组,存储数据
byte[] data=new byte[1024];
DatagramPacket packet=new DatagramPacket(data, data.length);
//接收数据,此方法是阻塞式的,若没有收到消息,会一直等待。
socket.receive(packet);
//得到接收到的数据
String datas=new String(packet.getData(),0,packet.getLength());
//得到发送方用来返送数据的端口
int sendPort=packet.getPort();
//得到发送发的IP地址
String sendIP=packet.getAddress().getHostAddress();
System.out.println("收到的数据是 "+datas+"源端口是 "+sendPort+"源IP是 "+sendIP);
socket.close();

}


5.3 发送端从键盘输入,接收端一直监听

代码:(键盘接收消息发送)

static void udpSendBykeyBoard() throws Exception{
String hostName="127.0.0.1";
//创建DatagramSocket对象
DatagramSocket datagramSocket=new DatagramSocket();
//System.in从键盘录入
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
String datas=null;
//readLine()是阻塞式的,所以不会造成死循环
while((datas=reader.readLine())!=null){
if(datas.equals("over"))
break;
byte[] bytes=datas.getBytes();
//构建DatagramPacket类,其封装了要发送的数据和目的地信息
DatagramPacket datagramPacket=new DatagramPacket(bytes, bytes.length,InetAddress.getByName(hostName),9999);
//发送
datagramSocket.send(datagramPacket);
}

//关闭资源
datagramSocket.close();
}


代码:(接收端一直处于接收状态)

static void udpReceive()throws Exception{
//创建Socket,并且必须指明那个端口用来接收消息
DatagramSocket socket=new DatagramSocket(9999);
while(true){
//创建字节数组,存储数据
byte[] data=new byte[1024];
DatagramPacket packet=new DatagramPacket(data, data.length);
//接收数据,此方法是阻塞式的,若没有收到消息,会一直等待。
socket.receive(packet);
//得到接收到的数据
String datas=new String(packet.getData(),0,packet.getLength());
//得到发送方用来返送数据的端口
int sendPort=packet.getPort();
//得到发送发的IP地址
String sendIP=packet.getAddress().getHostAddress();
System.out.println("收到的数据是 "+datas+"源端口是 "+sendPort+"源IP是 "+sendIP);
}

//socket.close();

}


5.4 用UDP发送和接收文本文件。

发送代码:

static void udpSendFile()throws Exception{
String hostName="127.0.0.1";//目标端口
DatagramPacket packet=null;
InetAddress address=InetAddress.getByName(hostName);
DatagramSocket socket=new DatagramSocket();
//创建字符缓冲读出流
BufferedReader reader=new BufferedReader(new FileReader("D:/code.java"));
String data=null;

//读取一行数据,然后发送出去。readLine()方法阻塞。
while((data=reader.readLine())!=null){
packet=new DatagramPacket(data.getBytes(), data.getBytes().length,address,9999);
socket.send(packet);
}
//关闭资源
socket.close();
reader.close();

}


接收代码:

static void udpReceiveFile()throws Exception{
//创建一个字符缓冲写入流
BufferedWriter writer=new BufferedWriter(new FileWriter("F:/teset.java"));
//创建DatagramSocket对象,9999是监听的端口
DatagramSocket socket=new DatagramSocket(9999);
socket.setSoTimeout(4000);//设置超时为4秒,若4秒中没有数据,报超时异常,退出程序

while(true){
byte[] datas=new byte[1024];
DatagramPacket packet=new DatagramPacket(datas, datas.length);
//阻塞式方法。所以可以使用while循环
socket.receive(packet);
String string=new String(packet.getData(),0,packet.getLength());
System.out.println(string);
//每读到一行数据,就写入文件,并且再写入一个换行,刷新。
writer.write(string);
writer.newLine();
writer.flush();
}
}


6. TCP的发送和接收

TCP分为客户端和服务端。客户端和 服务端的对象也不尽相同。

客户端只有一个Socket,用来发送和接收消息。客户端的Socket在创建的时候可以指定服务端的端口和IP地址。

服务端有一个ServerSocket,其accept()方法用来等待客户端连接。ServerSocket创建的时候必须指明监听的端口。

这个Socket对象的使用和客户端的Socket是相同的。其中accept()方法是阻塞式的,只有有客户端连接,才能获取客户端的Socket。一个服务端可以有多个客户端去连接。每连接一个客户端,就创建一个Socket对象

Socket可以获取InputSream用来读取数据,获取OutputStream用来向Socket发送数据

实现客户端向服务端发送一条消息,服务端收到消息后,向该客户端反馈一条消息。

客户端代码:

static void tcpClient()throws Exception{
//创建输入和输出流
InputStream inputStream=null;
OutputStream outputStream=null;
//创建Socket,客户端需要指明服务端(目的)的IP地址和端口号
Socket socket=new Socket("127.0.0.1",10001);
//得到输出流
outputStream=socket.getOutputStream();
//向socket写入数据并且发送
outputStream.write("我是TCP客户端,正在向服务端发消息".getBytes());

//接收服务端发过来的消息
inputStream=socket.getInputStream();
byte[] datas=new byte[1024];
//读取消息
int len=inputStream.read(datas);
System.out.println("客户端收到消息--"+new String(datas,0,len));

//关闭资源
socket.close();

}


服务端代码:

static void tcpServer()throws Exception{
InputStream inputStream=null;
OutputStream outputStream=null;
//创建ServerSocket对象,必须指明监听的端口
ServerSocket serverSocket=new ServerSocket(10001);
//该方法是阻塞式方法,每有一个客户端连接,就与之建立一个对应的Socket对象。
Socket socket=serverSocket.accept();

//接收客户端发过来的数据
inputStream=socket.getInputStream();
byte []datas=new byte[1024];
int len=inputStream.read(datas);
System.out.println("服务端收到消息--"+new String(datas,0,len));

//向客户端发送数据
outputStream=socket.getOutputStream();
outputStream.write("客户端,你好啊".getBytes());

//关闭资源
socket.close();
//现实中,serverSocket是不能关闭的,因为要一直等待其他客户端的连接
serverSocket.close();

}


6.1 TCP发送和接收图片

发送代码:

static void tcpSendPicture() throws Exception{
//创建字节缓冲读出流
BufferedInputStream inputStream=new BufferedInputStream(new FileInputStream("D:/view.jpg"));
//创建Socket,客户端需要指明服务端(目的)的IP地址和端口号
Socket socket=new Socket("127.0.0.1",10001);
//将socket的输出输出流转换为缓冲输出流。
BufferedOutputStream outputStream=new BufferedOutputStream(socket.getOutputStream());
int datas=0;
//注意,datas是读到的数据,而不是数据长度。从文件读到数据缓冲区满了以后,使用outputStream发给服务端
while((datas=inputStream.read())!=-1){
outputStream.write(datas);
}

//通知服务端发送完毕,服务端收到此消息会停止继续接收数据。
socket.shutdownOutput();
//关闭资源。
socket.close();
inputStream.close();

}


服务端接收代码:

static void tcpReceivePicture() throws Exception{
//创建ServerSocket ,绑定监听端口
ServerSocket serverSocket=new ServerSocket(10001);
Socket socket=serverSocket.accept();
//将socket的输入流转换为缓冲输入流,方便读写。
BufferedInputStream inputStream=new BufferedInputStream(socket.getInputStream());
//创建接收数据的IO流对象
BufferedOutputStream outputStream=new BufferedOutputStream(new FileOutputStream("F:/view_copu.jpg"));

//datas是读到的数据,不是数据长度。
int datas=0;
while((datas=inputStream.read())!=-1){
outputStream.write(datas);
}
//关闭资源
serverSocket.close();
serverSocket.close();
outputStream.close();
}


7. URLConnection

代码:

static void URLtest() throws Exception{
URL url =new URL("https://www.baidu.com/");
URLConnection urlConnection=url.openConnection();

InputStream inputStream=urlConnection.getInputStream();
byte[] datas=new byte[1024];
int len=0;
while((len=inputStream.read(datas))!=-1){
System.out.println(new String(datas,0,len));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 网络编程 TCP-UDP