2015年做那个网站致富,钢结构工程外包项目网,分类信息的网站如何推广,洛阳建设工程网站一、网络编程
1.概述
可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)。java.net,*包下提供了网络编程的解决方案!
基本的通信架构 基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)。 网络通信的…一、网络编程
1.概述
可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)。java.net,*包下提供了网络编程的解决方案!
基本的通信架构 基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)。 网络通信的关键三要素 IP地址
IP(Internet Protocol):全称”互联网协议地址”是分配给上网设备的唯一标志。IP地址有两种形式:IPV4、IPV6 IPv6:共128位号称可以为地球每一粒沙子编号。IPV6分成8段表示每段每四位编码成一个十六进制位表示数之间用冒号(:)分开。 IP域名
公网IP:是可以连接互联网的IP地址;内网IP:也叫局域网IP只能组织机构内部使用。192.168.开头的就是常见的局域网地址范围即为192.168.0.0–192.168.255.255专门为组织机构内部使用。
特殊IP地址 127.0.0.1、localhost:代表本机IP只会寻找当前所在的主机。 IP常用命令: ipconfig:查看本机IP地址。 ping IP地址:检查网络是否连通。
1.1 InetAddress
代表IP地址。
端口
标记正在计算机设备上运行的应用程序的被规定为一个16 位的二进制范围是 0~65535
分类
周知端口:0~1023被预先定义的知名应用占用(如:HTTP占用 80FTP占用21)注册端口:1024~49151分配给用户进程或某些应用程序。动态端口:49152到65535之所以称为动态端口是因为它 一般不固定分配某种进程而是动态分配。注意:我们自己开发的程序一般选择使用注册端口且一个设备中不能出现两个程序的端口号一样否则出错。
通信协议
网络上通信的设备事先规定的连接规则以及传输数据的规则被称为网络通信协议
开放式网络互联标准:OSI网络参考模型
OSI网络参考模型:全球网络互联标准。TCP/IP网络模型:事实上的国际标准。
1.2 重要知识点传输层的2个通信协议
UDP(User Datagram Protocol):用户数据报协议;TCP(Transmission ControlProtocol):传输控制协议。
UDP协议
特点:无连接、不可靠通信。通讯效率高语音通话 视频直播不事先建立连接数据按照包发一包数据包含:自己的IP、程序端口目的地IP、程序端口和数据(限制在64KB内)等。发送方不管对方是否在线数据在中间丢失也不管如果接收方收到数据也不返回确认故是不可靠的。
TCP协议
特点:面向连接、可靠通信。通信效率相对不高 网页 文件下载 支付TCP的最终目的:要保证在不可靠的信道上实现可靠的传输。TCP主要有三个步骤实现可靠传输:三次握手建立连接传输数据进行确认四次挥手断开连接。TCP协议:三次握手建立可靠连接 可靠连接:确定通信双方收发消息都是正常无问题的!(全双工)传输数据会进行确认以保证数据传输的可靠性 TCP协议:四次握手断开连接 目的:确保双方数据的收发都已经完成! 2. UDP通信-快速入门
UDP通信
特点:无连接、不可靠通信。不事先建立连接;发送端每次把要发送的数据(限制在64KB内)、接收端IP、等信息封装成一个数据包发出去就不管了。Java提供了一个java.net.DatagramSocket类来实现UDP通信。
import java.net.*;public class Client {public static void main(String[] args) throws Exception {//1. 创建客户端对象发韭菜出去的人DatagramSocket socket new DatagramSocket();//2. 创建数据包对象封装要发出去得数据创建一个韭菜盒子/* public DatagramPacket(byte buf[], int length,InetAddress address,int port)参数一:封装要发出去的数据。参数二:发送出去的数据大小(字节个数参数三服务端的IP地址找到服务端主机参数四服务端程序的端口。*/byte[] bytes 我是客户端向您发送数据.getBytes();DatagramPacket packet new DatagramPacket(bytes,bytes.length,InetAddress.getLocalHost(),6666);//3. 开始正式发送这个数据包出去了socket.send(packet);System.out.println(客户端数据发送完毕~~~);socket.close();//释放资源}
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;public class Server {public static void main(String[] args) throws Exception {//1. 创建一个服务端对象创建一个接韭菜的人 注册端口DatagramSocket socket new DatagramSocket(6666);//2. 创建一个数据包对象用于接收数据的创建一个韭菜盒子byte[] buf new byte[1024 * 64];DatagramPacket packet new DatagramPacket(buf, buf.length);//3. 开始正式使用数据包来接收客户端发来的数据socket.receive(packet);//4. 从字节数组中把接收到的数据直接打印出来// 接收多少就倒出多少 获取本次数据包接收了多少数据int len packet.getLength();String s new String(buf, 0, len);System.out.println(s);String hostAddress packet.getAddress().getHostAddress();int port packet.getPort();System.out.println(hostAddress : port);socket.close();//释放资源}
}UDP通信 多发多收 edit configures-allow 多开 apply即可躲开client程序的
package com.jingwei;import java.net.*;
import java.util.Scanner;public class Client {public static void main(String[] args) throws Exception {//1. 创建客户端对象发韭菜出去的人DatagramSocket socket new DatagramSocket();//可以分配端口 或者不填写自动分配//2. 创建数据包对象封装要发出去得数据创建一个韭菜盒子/* public DatagramPacket(byte buf[], int length,InetAddress address,int port)参数一:封装要发出去的数据。参数二:发送出去的数据大小(字节个数参数三服务端的IP地址找到服务端主机参数四服务端程序的端口。*/Scanner sc new Scanner(System.in);while (true) {System.out.println(请说);String msg sc.nextLine();if(exit.equals(msg)) {System.out.println(退出成功);socket.close();break;}byte[] bytes msg.getBytes();DatagramPacket packet new DatagramPacket(bytes,bytes.length,InetAddress.getLocalHost(),6666);//3. 开始正式发送这个数据包出去了socket.send(packet);}System.out.println(客户端数据发送完毕~~~);}
}
package com.jingwei;import java.net.DatagramPacket;
import java.net.DatagramSocket;public class Server {public static void main(String[] args) throws Exception {//1. 创建一个服务端对象创建一个接韭菜的人 注册端口DatagramSocket socket new DatagramSocket(6666);//2. 创建一个数据包对象用于接收数据的创建一个韭菜盒子byte[] buf new byte[1024 * 64];DatagramPacket packet new DatagramPacket(buf, buf.length);while (true) {//3. 开始正式使用数据包来接收客户端发来的数据socket.receive(packet);//4. 从字节数组中把接收到的数据直接打印出来// 接收多少就倒出多少 获取本次数据包接收了多少数据int len packet.getLength();String s new String(buf, 0, len);System.out.println(s);String hostAddress packet.getAddress().getHostAddress();int port packet.getPort();System.out.println(hostAddress : port);System.out.println(-----------------------);}}
}
3. TCP通信
特点:面向连接、可靠通信。通信双方事先会采用“三次握手”方式建立可靠连接实现端到端的通信;底层能保证数据成功传给服务端。Java提供了一个java.net.Socket类来实现TCP通信。 一发一收
package com.jingwei;import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;public class SocketClient {public static void main(String[] args) throws IOException {System.out.println(服务端启动成功);//1. 创建ServerSocket的对象同时为服务端注册端口。ServerSocket serverSocket new ServerSocket(8888);//2. 使用ServerSocket对象调用accept方法等待客户端的连接请求。Socket socket serverSocket.accept();//3. 从socket通信管道中得到一个字节输入流InputStream is socket.getInputStream();//4. 把原始的字节输入流包装成数据输入流DataInputStream dis new DataInputStream(is);//5. 使用数据输入流读取客户端发送过来的消息String s dis.readUTF();System.out.println(s);//其实我们也可以获取客户端的IP地址SocketAddress remoteSocketAddress socket.getRemoteSocketAddress();System.out.println(remoteSocketAddress);dis.close();socket.close();}
}
package com.jingwei;import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;public class SocketServer {public static void main(String[] args) throws IOException {//1. 创建Socket对象并同时请求与服务器程序的连接。Socket socket new Socket(127.0.0.1, 8888);//2. 从Socket通信管道中得到一个字节输出流用来发数据给服务端程序OutputStream os socket.getOutputStream();//3. 把低级的字节输出流包装成数据输出流DataOutputStream dos new DataOutputStream(os);//4. 开始写数据出去了dos.writeUTF(在一起好吗);dos.close();socket.close();//释放连接资源}
}
多发多收
package com.jingwei;import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;public class SocketServer {public static void main(String[] args) throws IOException {//1. 创建Socket对象并同时请求与服务器程序的连接。Socket socket new Socket(127.0.0.1, 8888);//2. 从Socket通信管道中得到一个字节输出流用来发数据给服务端程序OutputStream os socket.getOutputStream();//3. 把低级的字节输出流包装成数据输出流DataOutputStream dos new DataOutputStream(os);Scanner sc new Scanner(System.in);while (true) {System.out.println(请说);//4. 开始写数据出去了String msg sc.nextLine();if(exit.equals(msg)){dos.close();socket.close();break;}dos.writeUTF(msg);dos.flush();}// dos.close();
//
// socket.close();//释放连接资源}
}
package com.jingwei;import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;public class SocketClient {public static void main(String[] args) throws IOException {System.out.println(服务端启动成功);//1. 创建ServerSocket的对象同时为服务端注册端口。ServerSocket serverSocket new ServerSocket(8888);//2. 使用ServerSocket对象调用accept方法等待客户端的连接请求。Socket socket serverSocket.accept();//3. 从socket通信管道中得到一个字节输入流InputStream is socket.getInputStream();//4. 把原始的字节输入流包装成数据输入流DataInputStream dis new DataInputStream(is);while (true) {//5. 使用数据输入流读取客户端发送过来的消息try {String s dis.readUTF();System.out.println(s);//其实我们也可以获取客户端的IP地址SocketAddress remoteSocketAddress socket.getRemoteSocketAddress();System.out.println(remoteSocketAddress);} catch (IOException e) {System.out.println(socket.getRemoteSocketAddress()离线了);dis.close();socket.close();break;}}
// dis.close();
// socket.close();}
}目前我们开发的服务端程序是否可以支持与多个客户端同时通信?
不可以的。因为服务端现在只有一个主线程只能处理一个客户端的消息 package com.jingwei;import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;public class SocketServer {public static void main(String[] args) throws IOException {//1. 创建Socket对象并同时请求与服务器程序的连接。Socket socket new Socket(127.0.0.1, 8888);//2. 从Socket通信管道中得到一个字节输出流用来发数据给服务端程序OutputStream os socket.getOutputStream();//3. 把低级的字节输出流包装成数据输出流DataOutputStream dos new DataOutputStream(os);Scanner sc new Scanner(System.in);while (true) {System.out.println(请说);//4. 开始写数据出去了String msg sc.nextLine();if(exit.equals(msg)){dos.close();socket.close();break;}dos.writeUTF(msg);dos.flush();}// dos.close();
//
// socket.close();//释放连接资源}
}
package com.jingwei;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class SocketClient {public static void main(String[] args) throws IOException {System.out.println(服务端启动成功);//1. 创建ServerSocket的对象同时为服务端注册端口。ServerSocket serverSocket new ServerSocket(8888);//2. 使用ServerSocket对象调用accept方法等待客户端的连接请求。while (true) {Socket socket serverSocket.accept();System.out.println(有人上线了socket.getRemoteSocketAddress());new ServerReaderThread(socket).start();}
// dis.close();
// socket.close();}
}
package com.jingwei;import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;public class ServerReaderThread extends Thread{private Socket socket;public ServerReaderThread(Socket socket) {this.socket socket;}Overridepublic void run() {try {InputStream inputStream socket.getInputStream();DataInputStream dataInputStream new DataInputStream(inputStream);while (true){try {String msg dataInputStream.readUTF();System.out.println(msg);} catch (IOException e) {System.out.println(socket.getRemoteSocketAddress()下线了);dataInputStream.close();socket.close();break;}}} catch (IOException e) {throw new RuntimeException(e);}}
}
TCP通信-综合案例
即时通信-群聊实现一个简易版的BS架构
题目要求从浏览器中访问服务器 并立即让服务器响应一个很简单的网页给浏览器展示 网页内容就是“我666” 注意:服务器必须给浏览器响应HTTP协议规定的数据格式否则浏览器不识别返回的数据 package com.jingwei;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class SocketClient {public static void main(String[] args) throws IOException {System.out.println(服务端启动成功);//1. 创建ServerSocket的对象同时为服务端注册端口。ServerSocket serverSocket new ServerSocket(8888);//2. 使用ServerSocket对象调用accept方法等待客户端的连接请求。while (true) {Socket socket serverSocket.accept();System.out.println(有人上线了socket.getRemoteSocketAddress());
// new ServerReaderThread(socket).start();new ServerWriterThread(socket).start();}
// dis.close();
// socket.close();}
}
package com.jingwei;import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;public class ServerWriterThread extends Thread {private Socket socket;public ServerWriterThread(Socket socket) {this.socket socket;}Overridepublic void run() {try {OutputStream outputStream socket.getOutputStream();PrintStream printStream new PrintStream(outputStream);printStream.println(Http/1.1 200 OK);printStream.println(Content-Type: text/html;charsetutf-8);printStream.println();printStream.println(!DOCTYPE html);printStream.println(html);printStream.println(head);printStream.println(titleServer Writer/title);printStream.println(/head);printStream.println(body);printStream.println(h1Server Writer/h1);printStream.println(/body);printStream.println(/html);printStream.flush();printStream.close();socket.close();} catch (IOException e) {throw new RuntimeException(e);}}}
拓展知识 每次请求都开一个新线程到底好不好? 高并发时容易宕机!
package com.day19;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;public class SocketClient {public static void main(String[] args) throws IOException {System.out.println(服务端启动成功);//1. 创建ServerSocket的对象同时为服务端注册端口。ServerSocket serverSocket new ServerSocket(8888);//创建出一个线程池负责处理通信管道的任务ThreadPoolExecutor threadPoolExecutor new ThreadPoolExecutor(20 * 2, 20 * 2, 0, TimeUnit.SECONDS,new ArrayBlockingQueue(8), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());//2. 使用ServerSocket对象调用accept方法等待客户端的连接请求。while (true) {Socket socket serverSocket.accept();System.out.println(有人上线了socket.getRemoteSocketAddress());
// new ServerReaderThread(socket).start();//3、把这个客户端对应的socket通信管道交给一个独立的线程负责处理。threadPoolExecutor.execute(new ServerWriterRunnable(socket));}
// dis.close();
// socket.close();}
}
package com.day19;import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;public class ServerWriterRunnable implements Runnable {private Socket socket;public ServerWriterRunnable(Socket socket) {this.socket socket;}Overridepublic void run() {try {OutputStream outputStream socket.getOutputStream();PrintStream printStream new PrintStream(outputStream);printStream.println(Http/1.1 200 OK);printStream.println(Content-Type: text/html;charsetutf-8);printStream.println();printStream.println(!DOCTYPE html);printStream.println(html);printStream.println(head);printStream.println(titleServer Writer/title);printStream.println(/head);printStream.println(body);printStream.println(h1Server Writer/h1);printStream.println(/body);printStream.println(/html);printStream.flush();printStream.close();socket.close();} catch (IOException e) {throw new RuntimeException(e);}}}