网络编程3要素:
1.IP地址:目的主机的唯一标识
2.port端口号:目的主机上的目标程序的唯一标识
3.protocol:协议;分为udp和tcp
通信原理:
1.无论是udp还是tcp其通信底层都是由socket(套接字:包括IP和port端口两部分)来实现的;
2.数据:
udp将数据封装在数据报包(DatagramPacket)对象内;
TCP通信的两端直接是输入输出流;
原理图:
下面通过代码来加深理解:
一、基于UDP的简单通信程序
接收端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 创建socket
DatagramSocket socket = new DatagramSocket(9999);
// 创建接受包
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
// 接受数据
socket.receive(packet);// 阻塞式
// 解析数据
String ip = packet.getAddress().getHostAddress();
String content = new String(packet.getData(), 0,
packet.getLength());
System.out.println("From:" + ip + "\n" + "content: " + content);
// 释放资源
socket.close();
}
}
发送端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class SendDemo {
public static void main(String[] args) throws IOException,
UnknownHostException {
// 创建socket对象
DatagramSocket socket = new DatagramSocket();
// 创建发送包(ip+port在包上,因为是把包发送出去,让包去寻找目的主机上的目标端口)
byte[] buf = "hello udp !".getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress
.getByName("192.168.1.100"), 9999);
// 发送
socket.send(packet);
// 释放资源
socket.close();
}
}
二、基于TCP的简单通信程序
接收端:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务器socket对象
ServerSocket ss = new ServerSocket(8888);
// 监听客户端的连接
Socket socket = ss.accept();// 阻塞
// 获取输入流
InputStream is = socket.getInputStream();
byte[] buf = new byte[1024];
// This method blocks until input data is available, end of file is
// detected, or an exception is thrown.
int len = is.read(buf);
String content=new String(buf, 0, len);
System.out.println("收到内容:"+content);
//获取输出流,并向客户端反馈(可选)
OutputStream os=socket.getOutputStream();
os.write("Server Received!".getBytes());
//释放资源
socket.close();
//注意:服务器一般是不关的
//ss.close();
}
}
客户端:
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws Exception {
// 创建客户端socket对象
Socket s = new Socket("192.168.1.100", 8888);
// 获取输出流,并写入数据
OutputStream os = s.getOutputStream();
os.write("hello ,tcp".getBytes());
// 获取输入流,从中取出服务端的反馈信息
InputStream is = s.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
String content = new String(buf, 0, len);
System.out.println("反馈内容:" + content);
}
}