网络编程
可以让程序进行数据交互
目录
一、架构
CS:客户端-服务端——QQ 微信 LOL
BS:浏览器-服务端——京东 淘宝
区别: BS模型不需要程序员开发客户端,可以直接浏览器访问服务器
二、三要素
2.1IP地址
服务器在网络中的唯一标识
分类:Ipv4、Ipv6、域名
特殊IP:本机地址 127.0.0.1 、localhost
命令:ipconfig 查看电脑ip、ping ip地址 测试联通
2.2端口号
1、0-1023 预先占用
2、设备在服务器中的唯一标识
3、同一台电脑中不能有两个程序占用同一个端口
2.3协议
通信标准
udp:不可靠 高效
tcp:可靠 三次握手 四次挥手
三、ip地址
InetAddress public static InetAddress getLocalHost() 获取本机IP,会以一个inetAddress的对象返回 public static InetAddress getByName(String host) 根据ip地址或者域名,返回一个inetAddress对象 public String getHostName() 获取该ip地址对象对应的主机名 public String getHostAddress() 获取该ip地址对象中的ip地址信息 public boolean isReachable(int timeout) 在指定毫秒内,判断主机与该ip对应的主机是否能连通
代码如下(示例):
public static void main(String[] args) throws Exception {
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
InetAddress host = InetAddress.getByName("www.baidu.com");
System.out.println(host);
String hostName = host.getHostName();
System.out.println(hostName);
String hostAddress = host.getHostAddress();
System.out.println(hostAddress);
boolean reachable = host.isReachable(10);
System.out.println(reachable);
}
四、udp
4.1入门案例
客户端 发数据 实现步骤 1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人 2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子 3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜 4. 释放资源 使用的API DatagramSocket: 客户端、服务端 public DatagramSocket()创建客户端的Socket对象, 系统会随机分配一个端口号 public void send(DatagramPacket dp) 发送数据包 DatagramPacket:数据包 public DatagramPacket(byte[] buf, int length, InetAddress address, int port) 创建发出去的数据包对象
代码如下(示例):
public class Client {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket();
String msg = "你好啊";
byte[] bytes = msg.getBytes();
InetAddress host = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.1.168"), 7777);
socket.send(packet);
socket.close();
}
}
服务端 接收数据(必须用7777) 实现步骤 1. 创建DatagramSocket对象并指定端口(服务端对象) ---->接韭菜的人 2. 创建DatagramPacket对象接收数据(数据包对象)---->韭菜盘子 3. 使用DatagramSocket对象的receive方法,传入DatagramPacket对象 ---->开始接收韭菜 4. 打印结果 5. 释放资源 使用的API DatagramSocket: 客户端、服务端 public DatagramSocket(int port) 创建服务端的Socket对象, 并指定端口号 public void receive(DatagramPacket p) 使用数据包接收数据 DatagramPacket:数据包 public DatagramPacket(byte[] buf, int length) 创建用来接收数据的数据包 public int getLength() 获取数据包,实际接收到的字节个数
代码如下(示例):
public class Server {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(7777);
byte[] bytes = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
socket.receive(packet);
String string = new String(bytes, 0, packet.getLength());
System.out.println(packet.getAddress().getHostAddress()+":"+string);
socket.close();
}
}
4.2多发多收
客户端
代码如下(示例):
public class Client {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket();
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("请输入要发送的数据:");
String str = scanner.next();
String msg = str;
if ("exit".equals(str)){
break;
}
byte[] bytes = msg.getBytes();
InetAddress host = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, host, 7777);
socket.send(packet);
}
socket.close();
}
}
服务端
代码如下(示例):
public class Server {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(7777);
byte[] bytes = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
while (true){
socket.receive(packet);
String string = new String(bytes, 0, packet.getLength());
System.out.println(packet.getAddress().getHostAddress()+":"+string);
}
//socket.close();
}
}
五、tcp
5.1入门案例
客户端 发数据 实现步骤 1. 创建客户端的Socket对象,请求与服务端的连接 2. 使用socket对象调用getOutputStream()方法得到字节输出流 3. 使用字节输出流完成数据的发送 4. 释放资源:关闭socket管道 使用的API public Socket(String host , int port) 根据指定的服务器ip、端口号请求与服务端建立连接,连接通过,就获得了客户端socket public OutputStream getOutputStream() 获得字节输出流对象 public InputStream getInputStream() 获得字节输入流对象
代码如下(示例):
public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8888);
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeUTF("你好呀!");
oos.close();
socket.close();
}
}
服务端 接收数据 实现步骤 1. 创建ServerSocket对象,注册服务端端口 2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象 3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收 4. 释放资源:关闭socket管道 使用的API public ServerSocket(int port) 为服务端程序注册端口 public Socket accept() 阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象
代码如下(示例):
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
Socket accept = serverSocket.accept();
InputStream is = accept.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
String msg = ois.readUTF();
System.out.println(accept.getInetAddress().getHostAddress()+":"+ accept.getPort() +"客户端说:" + msg);
ois.close();
accept.close();
serverSocket.close();
}
}
5.2多发多收
客户端
代码如下(示例):
public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8888);
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("请输入要发送的数据:");
String msg = scanner.next();
if("exit".equals(msg)){
break;
}
oos.writeUTF(msg);
oos.flush();
}
oos.close();
socket.close();
}
}
服务端
代码如下(示例):
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
Socket accept = serverSocket.accept();
InputStream is = accept.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
while (true){
String msg = ois.readUTF();
System.out.println(accept.getInetAddress().getHostAddress()+":"+ accept.getPort() +"客户端说:" + msg);
}
//ois.close();
//accept.close();
//serverSocket.close();
}
}
5.3多客户端通信
客户端
代码如下(示例):
public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8888);
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("请输入要发送的数据:");
String msg = scanner.next();
if("exit".equals(msg)){
break;
}
oos.writeUTF(msg);
oos.flush();
}
oos.close();
socket.close();
}
}
服务端
代码如下(示例):
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
while (true){
Socket accept = serverSocket.accept();
new Thread(new socketRunnable(accept)).start();
}
}
}
class socketRunnable implements Runnable{
private Socket accept;
public socketRunnable(Socket accept) {
this.accept = accept;
}
@Override
public void run() {
InputStream is = null;
ObjectInputStream ois = null;
try {
is = accept.getInputStream();
ois = new ObjectInputStream(is);
while (true){
String msg = ois.readUTF();
System.out.println(accept.getInetAddress().getHostAddress()+":"+ accept.getPort() +"客户端说:" + msg);
}
}catch (Exception e){
System.out.println("客户端断开连接");
}finally {
try {
ois.close();
is.close();
accept.close();
}catch (Exception e){}
}
}
}
六、bs架构
代码如下(示例):
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8080);
while (true){
Socket accept = serverSocket.accept();
new Thread(new socketRunnable(accept)).start();
}
}
}
class socketRunnable implements Runnable{
private Socket accept;
public socketRunnable(Socket accept) {
this.accept = accept;
}
@Override
public void run() {
PrintWriter writer = null;
try {
System.out.println("客户端连接成功"+accept.getPort());
writer = new PrintWriter(accept.getOutputStream());
writer.println("HTTP/1.1 200 OK");
writer.println("Content-Type : text/html;charset=UTF-8");
writer.println("");
writer.println("<div style=color:red>你好,啦啦啦</div>");
writer.flush();
}catch (Exception e){
}finally {
try {
writer.close();
accept.close();
}catch (Exception e){}
}
}
}
总结
以上就是今天学习的内容。