小知识点:
网络编程:主要解决计算机间数据传输
不需要html页面可以达到数据传输:QQ,微信
网页编程:继续Html页面基础上数据交互:OA,天猫。。。
java方向:web方向,annrod常用Socket方式传输
计算机网路:分布在不同地域的计算机通过外部设备传输数据
网路通讯三要素:IP,端口号(哪个应用程序使用),协议
IP地址分类:网路号,主机号;子网掩码是标明哪个是网络号
A类地址:一个网络号+三个主机号 政府单元2^24个
B类地址:2+2 事业单位(学校,银行)2^16
C类地址:3+1 私人使用2^8
InetAddress类(IP类)
服务器集群:一个计算机访问百度,在对象的电信dns服务器中可能有多个,每个又有很多子服务器,后来的那么多服务器集合叫服务器集群
端口号:0~2^16-1;0~1023:系统紧密绑定一些服务
1024~65535:我们可以使用;1024是个分界点
网络通讯的协议:
UDP:不需要建立连接通讯
TCP:需要建立连接的通讯
1.UDP
什么时候数据可能丢失:
a.带宽不足b.cpu不足
用法:a.建DatagramSocket
b.DatagramPacket封装数据为数据包(数据包大小64kb,该有的信息都有)
c.发送数据:.send();;接收数据receive();
例子:
基本例子:
发送端:
DatagramSocket ds=new DatagramSocket();
String content="你好,我是第一次使用udp!";
//装载数据
DatagramPacket dp=new DatagramPacket(content.getBytes(),content.getBytes().length,InetAddress.getLocalHost(),1025);
//发送数据
ds.send(dp);
ds.close();
接收端
DatagramSocket sd=new DatagramSocket(1025);
byte[] buffer=new byte[1024];
DatagramPacket dp=new DatagramPacket(buffer,buffer.length);
while(true){
sd.receive(dp);
System.out.println(new String(buffer,0,dp.getLength()));
Thread.sleep(1000);
}
群聊例子:
这个分三个类:一个发送,一个接收,一个主程序(用到的是多线程编程)
发送发:
//群聊发送端
public class ChatSender extends Thread { @Override public void run() { try { //建立udp的服务 DatagramSocket socket = new DatagramSocket(); //准备数据,把数据封装到数据包中发送 BufferedReader keyReader = new BufferedReader(new InputStreamReader(System.in)); String line = null; DatagramPacket packet = null; while((line = keyReader.readLine())!=null){ //把数据封装 到数据数据包中,然后发送数据。 packet = new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("192.168.15.255"), 9090); //把数据发送出去 socket.send(packet); } //关闭 资源 socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
//群聊接收端
public class ChatReceive extends Thread { @Override public void run() { try { //建立udp的服务,要监听一个端口 DatagramSocket socket = new DatagramSocket(9090); //准备空的数据包存储数据 byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); boolean flag = true; while(flag){ socket.receive(packet); } //关闭资源 socket.close(); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
//主程序
public static void main(String[] args) { ChatReceive chatReceive = new ChatReceive(); chatReceive.start(); ChatSender chatSender = new ChatSender(); chatSender.start(); }
2.TCP
问题:为什么Service为是么不设计一个getInputStream,getOutputStream
因为服务端会接收多个客户端,对应的输入输出流就不好找了,唯一性的只有客户端的Socket才是唯一能确定连接服务端的
用法:客务端:a.建立Socket连接
b.获得输出流
c.关闭连接
服务端:a.建立监听连接
b.等待客户端请求连接
c.获取对应的输入输出流
d。挂壁资源
例子:
a.基础例子:
客户端:
/** * tcp客户端 * 1.建立Socket连接 * 2.获得输出流 * 3.关闭连接 * @author Administrator * */ public class tcpClient { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub Socket socket=new Socket(InetAddress.getLocalHost(),2000); //获得输出流 java.io.OutputStream outputStream = socket.getOutputStream(); outputStream.write("这是你的tcp文件".getBytes()); //获取到输入流对象,读取服务端回送的数据。 java.io.InputStream inputStream = socket.getInputStream(); byte[] buf = new byte[1024]; int length = inputStream.read(buf); System.out.println("客户端接收到的数据:"+ new String(buf,0,length)); socket.close(); } }
服务端
/** * tcp服务端 * 1.建立监听连接 * 2.等待客户端请求连接 * 3.获取对应的输入输出流 * 4。挂壁资源 * @author Administrator * */ public class tcpService { public static void main(String[] args) throws IOException { ServerSocket ss=new ServerSocket(2000); Socket s=ss.accept(); //获取Socket中的输入流 InputStream inputStream=s.getInputStream(); byte[] buf = new byte[1024]; int length = 0; length = inputStream.read(buf); System.out.println("服务端接收:"+ new String(buf,0,length)); //获取socket输出流对象,想客户端发送数据 OutputStream outputStream = s.getOutputStream(); outputStream.write("客户端你好啊!".getBytes()); //关闭资源 ss.close(); } }
b.客户端与服务端一问一答聊天。
1.如果使用BuffrerdReader的readline方法一定要加上\r\n才把数据写出。
2.使用字符流一定要调用flush方法数据才会写出。
聊天的客户端
public class ChatClient { public static void main(String[] args) throws IOException { //建立tcp的客户端服务 Socket socket = new Socket(InetAddress.getLocalHost(),9090); //获取socket的输出流对象。 OutputStreamWriter socketOut = new OutputStreamWriter(socket.getOutputStream()); //获取socket的输入流对象 BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //获取键盘的输入流对象,读取数据 BufferedReader keyReader = new BufferedReader(new InputStreamReader(System.in)); String line = null; //不断的读取键盘录入的数据,然后把数据写出 while((line = keyReader.readLine())!=null){ socketOut.write(line+"\r\n"); //刷新 socketOut.flush(); //读取服务端回送的数据 line = socketReader.readLine(); System.out.println("服务端回送的数据是:"+line); } //关闭资源 socket.close(); } }
聊天的服务端
public class ChatServer { public static void main(String[] args) throws IOException { //建立tcp的服务端 ServerSocket serverSocket = new ServerSocket(9090); //接受客户端的连接,产生一个SOcket Socket socket = serverSocket.accept(); //获取到Socket的输入流对象 BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //获取到Socket输出流对象 OutputStreamWriter socketOut = new OutputStreamWriter(socket.getOutputStream()); //获取键盘的输入流对象 BufferedReader keyReader = new BufferedReader(new InputStreamReader(System.in)); //读取客户端的数据 String line = null; while((line = socketReader.readLine())!=null){ System.out.println("服务端接收到的数据:"+ line); System.out.println("请输入回送给客户端的数据:"); line = keyReader.readLine(); socketOut.write(line+"\r\n"); socketOut.flush(); } //关闭资源 serverSocket.close(); } }
c.模拟Tomcat服务器
public class TomcatDemo extends Thread { Socket socket; public TomcatDemo(Socket socket){ this.socket = socket; } public void run() { try { //获取socket的输出流对象 OutputStream outputStream = socket.getOutputStream(); //把数据写到浏览器上 outputStream.write("<html><head><title>aaa</title></head><body>你好啊浏览器</body></html>".getBytes()); socket.close(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { //建立tcp的服务端 ServerSocket serverSocket = new ServerSocket(9090); //不断的接受客户端的连接 while(true){ Socket socket = serverSocket.accept(); new TomcatDemo(socket).start(); } } }
作业:
1. 编写一个服务端可以给多个客户端发送图片。 (多线程)
2. 实现登陆与注册 功能。
客户端与服务端连接的时候,就要提示客户端请选择功能。
客户端注册的时候,用户名与密码都是发送给服务端 的,服务端需要把数据保存到服务端的文件上。
登陆: 登陆的时候客户端输入用户名与密码发送给服务端,服务端需要校验,返回结果给客户端。