Java基础(23)网络编程

来源:互联网 发布:广西网络问政 编辑:程序博客网 时间:2024/05/23 20:25


一.网络编程-概述

1.找到对方的ip

2.数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这个数字 ,叫做 端口 (逻辑端口,不是摸得着的端口0-1024系统用了,范围0-65535

3.定义通信规则,这个通讯规则则称为协议。

国际组织定义了通用协议TCP/IP


网络编程在传输层和网际层之间


二.网络编程(IP地址)




import java.net.*;class  InetTextDemo{public static void main(String[] args) throws Exception{//InetAddress i = InetAddress.getLocalHost();//System.out.println(i.toString());//获取了地址和主机名 //打印ZGC-20130618MMD/192.168.126.1//System.out.println("address"+i.getHostAddress());//获取主机地址//System.out.println("address"+i.getHostName());//获取主机名InetAddress ia = InetAddress.getByName("www.baidu.com");//主机名字只有一个,但是IP地址不止一个InetAddress[] ias = InetAddress.getAllByName("www.baidu.com");for(InetAddress s:ias){System.out.println(s); //打印了两个www.baidu.com/119.75.218.70//www.baidu.com/119.75.217.109}System.out.println("name:address"+ia.toString());System.out.println("address"+ia.getHostAddress());System.out.println("name:"+ia.getHostName());}}

三.网络编程(TCP和UDP)


这些概念必须会,背也要背下来!!!

UDP(步话机,对方在不在不知道)不需要建立连接!聊天,视频(出现马赛克就是没传好),用的就是UDP只要速度快,丢包不重要,下载就必须是TCP,丢了等会打不打不来

TCP(电话),三次握手,1.你在吗 2.我在  3.哦好的,我知道你在了.


四.网络编程(socket)


Socket插座的意思,相当于港口(socket),然后小船在两个港口来回装货卸货

五.网络编程(UDP发送端)

需求:通过udp传输方式,将一段文字数据发送出去。

定义了一个发送端

思路:

1.建立udpsocket服务。(先要有端点。或者说是先找一邮局)

2.提供数据,并将数据封装到数据包中。(把东西装进去)

3.通过socket服务的发送功能,将数据包发出去(发出去)

4.关闭资源

 

要跟接受端配套使用,写成两个java文件!!!!!

import java.net.*;//发送端class InetTextDemo{public static void main(String[] args)throws Exception{///1.创建udp服务。通过DatagramSocket对象。//此类表示用来发送和接收数据报包的套接字。//数据报套接字是包投递服务的发送或接收点(!!!!)。每个在数据报套接字上发送或接收的包都是单独编址和路由的。DatagramSocket ds = new DatagramSocket(8888);//可以指定端口(8888),也可以不指定(系统会随机分配)//2.确定数据,并封装成数据包,DatagramPackset(byte[] buf , int length , InetAddress address  ,  int port)//DatagramPacket此类表示数据报包,数据报包用来实现无连接(!!!!)包投递服务byte[] buf = "woshi daxiong".getBytes();; //确定数据DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.126.1"),10000);//3.通过socket服务,将已有的数据包发送出去。通过send方法。ds.send(dp);//关闭资源ds.close();}}


 //接收端

要跟发送端配套使用,写成两个java文件!!!!!
//配套 网络编程-UDP发送端!!!
需求:
定义一个应用程序,用于接受udp协议传输的数据并处理的。
定义udp的接收端。
思路:
1.定义udp服务。通常会监听一个端口,其实就是给这个接受网络应用程序定义标识。
方便明确哪些数据过来应用程序可以处理。
2.定义一个数据包,因为要存储接受到的字节数据。因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。
3.通过socket服务的receive方法将收到的数据存入已定义好的数据包中。
4.通过数据包对象的特有功能麻将这些不同的数据取出,打印在控制台上。
5.关闭资源


class  InetRece{public static void main(String[] args) throws Exception{///1.创建udp服务。通过DatagramSocket对象。//此类表示用来发送和接收数据报包的套接字。//数据报套接字是包投递服务的发送或接收点(!!!!)。每个在数据报套接字上发送或接收的包都是单独编址和路由的。////不要放while(true)里面去了,否则不断创建10000端口,会出现BindException,因为已经被用了再用就会这样DatagramSocket ds = new DatagramSocket(10000);while(true){//2.定义一个数据包,因为要存储接受到的字节数据。因为数据包对象中有更多功能可以提取字节数据中的不同数据byte[] buf = new byte[1024];//DatagramPacket(byte[] buf, int length),构造 DatagramPacket,用来接收长度为 length 的数据包。DatagramPacket dp = new DatagramPacket(buf,buf.length);//3.通过服务的receive方法将收到数据存入数据包中ds.receive(dp); //阻塞式方法,没线程我就等//4.通过数据包的方法获取其中的数据//InetAddress getAddress()返回某台机器的IP地址(返回对象时InetAddress),此数据报将要发往该机器或者是从该机器接收到的。//String getHostAddress(),返回 IP 地址字符串(以文本表现形式)。String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());int port = dp.getPort();System.out.println(ip+"::"+data+"::"+port);//5.关闭资源//ds.close(); //使用while(true)就不用关闭了,一直在这等接收}}}

六.网络编程-UDP键盘录入数据

/之前只能说一句,然后现在这里可以通过键盘输入说很多.

import java.net.*;import java.io.*;//发送端class InetTextDemo{public static void main(String[] args)throws Exception{//1.建立端口DatagramSocket ds = new DatagramSocket(8888);//2.放入数据,并打包BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line = bufr.readLine()) != null)//readLine也是阻塞式方法{if("886".equals(line)){break;}  byte[] buf = line.getBytes();  // //192.168.1.255  。255是这个网段的广播地址,谁都能收到,这里就开始群聊了  //和下面的话效果一样  DatagramPacket dp = new DatagramPacket(buf, buf.length , InetAddress.getByName("192.168.126.1"),10001);//  DatagramPacket dp = new DatagramPacket(buf, buf.length , InetAddress.getByName("ZGC-20130618MMD"),10001);//发送数据ds.send(dp);}ds.close();}}


//网络编程-UDP键盘录入数据
//配套接收端

import java.net.*;//接收端class InetRece{public static void main(String[] args) throws Exception{//1.建立一个端点DatagramSocket ds = new DatagramSocket(10001);while(true){//定义一个数据包,接收数据byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);ds.receive(dp);String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());int port = dp.getPort();System.out.println(ip+"::"+data+"::"+port);//5.关闭资源//ds.socket(); //用了 while(true)就不用关闭}}}

七.网络编程-UDP聊天

这个要好好掌握以下!!!!

//把接收发送写在一个class里面
编写一个聊天程序。
有接收数据的部分,和发数据的部分。
这两部分需要同时执行
那就需要用到多线程技术。
一个线程控制收,一个线程控制发。
因为收和发动作是不一致的,所以要定义两个run方法。
而且这两个方法要封装到不同的类中。
import java.net.*;import java.io.*;class ChatSend implements Runnable{private DatagramSocket ds;ChatSend(DatagramSocket ds){this.ds = ds;}public void run(){try{BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line = bufr.readLine()) != null){if("byebye".equals(line)){break;}byte[] buf = line.getBytes();////255局域网每个都能收到DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.126.1"),10002);ds.send(dp);//ds.close(); //否则发一次就不能发了}}catch (Exception e){throw new RuntimeException("发送失败");}}}class ChatRece implements Runnable{private DatagramSocket ds;ChatRece(DatagramSocket ds){this.ds = ds;}public void run(){try{while(true)//一直开着,循环接收{byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);ds.receive(dp);String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(),0,dp.getLength());int port = dp.getPort();System.out.println("ip:"+ip+"data:"+data+"port"+port);}}catch (Exception e){throw new RuntimeException("接收失败");}}}class InetTextDemo{public static void main(String[] args) throws Exception{ChatSend  cs = new ChatSend(new DatagramSocket(5555));ChatRece  cr = new ChatRece(new DatagramSocket(10002));Thread t1 = new Thread(cs);Thread t2 = new Thread(cr);t1.start();t2.start();}}

八.网络编程-TCP传输

UDP叫发送端和接收端
TCP叫客户端和服务端


演示tcp传输
1.tcp分客户端和服务端
2.客户端对应的对象是socket
服务端对应的对象是serverSocket.


客户端
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。
因为tcp是面向连接的。所以在建立socket服务时。
就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输。


需求:给服务端发送一个文本数据。

import java.net.*;import java.io.*;class InetTextDemo{public static void main(String[] args) throws Exception{//public class Socket//此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点//1.创建客户端的socket服务。指定目的主机和端口Socket s =new Socket("192.168.126.1",10003);//2.为了发送数据,应该获取socket流中的输出流//socket基友输入流也有输出流//通路一建立流就有了,不用去newOutputStream out = s.getOutputStream();//不用特意去关闭,因为属于socket,socket没了,这个也没了out.write("wo shi daxiong ni shi shui".getBytes());s.close();}}

配套网络变成 Tcp-传输
需求;定义端点接收数据并打印在控制台上。

服务端:
1.建立服务短的socket服务。Serversocket();
2.获取连接过来的客户端对象
通过ServerSocket的accept方法。没有连接就会等,所以这个方法是阻塞式的。
3.客户端如果发过来数据,那么服务端要使用对应的客户段对象,并获取到该客户端对象的读取流(!!!!!)来读取发过来的数据,并打印在控制台
4.关闭服务端。(可选操作,一般服务器不关就像10086客服)
//客户端A向服务端建立连接,服务端就拿了A这个对象,A具备输入,输出两个对象
同理如果是B,也是这样
都用自己的输入输出流,就不会冲突(本该发给A的发给B了),有点像打10086,很多客服对应不同客户

import java.net.*;import java.io.*;class InetRece{public static void main(String[] args) throws Exception{//1.建立一个端点ServerSocket ss = new ServerSocket(10003);//2.获取客户端对象,通过accept方法来获取,Socket s = ss.accept(); //也是阻塞式的String ip = s.getInetAddress().getHostAddress();//打印看看谁连接上了System.out.println(ip+"....connected");//3.获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据//网络流InputStream in =s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf,0,len));s.close();//关闭客户端,关闭客户端连接,不浪费资源,让其他客户端可以连上来//ss.close();//关闭服务端,可选操作,一般不关}}


九.匹配网络编程-TCP输出2

延时tcp的传输的客户端和服务端的互访。
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息(就相当于连接上了,我来了)

客户端;
1.建立socket服务。指定要连接主机和端口。
2.获取socket流中的输出流,将数据写到该流中。通过网络发送给服务端。
3.获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
4.关闭客户端资源。
import java.net.*;import java.io.*;//客户端class InetTextDemo{public static void main(String[] args) throws Exception{//1.建立socket服务Socket s = new Socket("192.168.126.1",10004);//2.获取socket流中的输出流,将数据写到该流中。通过网络发送给服务端。(类似于我来了)OutputStream out = s.getOutputStream();out.write("wo lai le".getBytes());//3.获取socket流中的输入流,将服务端反馈的数据获取到,并打印。InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf); //返回的读取到的总字节数//阻塞式方法System.out.println(new String(buf,0,len));}}

//服务端
import java.net.*;import java.io.*;class InetRece{public static void main(String[] args) throws Exception{//1.建立Serversocket服务ServerSocket ss = new ServerSocket(10004);while(true){//2.获取客户端对象,通过accept来接收Socket s = ss.accept();//阻塞式方法//打印下谁连接上来了String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connected");//3.获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据InputStream in = s.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf, 0 , len));//对面一连上来,发一个  欢迎使用,写入到客户端的输出流OutputStream out = s.getOutputStream();out.write("欢迎使用".getBytes());}}}

十.网络变成TCP-练习

需求:建立一个文本转换服务器。
客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端。
而且客户端可以不断地进行文本转换。当客户端输入over时,转换结束。
分析:
客户端;
既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。
源:键盘录入。
目的:网络设备,网络输出流。
而且操作的是文本数据。可以选择字符流。


步骤
1.建立服务。
2.获取键盘录入。
3.将数据发给服务端。
4.后去服务端返回的大写数据。
5.结束,关资源。


都是文本数据,可以使用字符流进行操作,同时提高效率,加入缓冲。


import java.io.*;import java.net.*;//客户端class InetTextDemo{public static void main(String[] args) throws Exception{//1.建立Socket端点Socket s = new Socket("192.168.126.1",10009);//2.读取键盘数据,并把它写到客户端的输出流中////定义目的,将数据写入到Socket输出流。发给服务端。//注意(!!!!)要使用字节转换流,因为这里读到的是字节流BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//读取键盘数据BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//读取客户端的输入流BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null;while((line = bufr.readLine()) != null){if("over".equals(line))//输入over关闭客户端{break;}//把键盘读到的数据写到客户端的输出流中bufout.write(line);//如果不写newline()//那么只写了数据但是没写回车符,所以服务端的readLine(读到回车符才会停止)一直在读数据,不会停止bufout.newLine();bufout.flush();String str = bufin.readLine();  //上面写完之后,就会一直在这等着服务端返回大写数据,这个是阻塞式方法System.out.println("server:"+str);}bufr.close();//键盘录入关闭s.close();//socket关闭//在socket流中返回-1,然后对面的readLine底层调用read读到-1,服务端也就停止了}}


//匹配网络编程:TCP练习


该例子出现的问题。
现象:客户端和服务端都在莫名的等待。
为什么呢?
因为客户端和服务端都有阻塞式方法(readLIne(),要读到回车符(也就是换行符)(newline())才会停止)。这些方法没有读到结束标记。那么就一直等。
导致两端都在等待

import java.io.*;import java.net.*;//服务端class InetRece{public static void main(String[] args) throws Exception{//1.建立ServerSocket服务ServerSocket ss = new ServerSocket(10009);//2.从客户端的接收对象Socket s = ss.accept();//打谁连接上了String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"...连接上了");//从从客户端的输入流获取数据BufferedReader bufin= new BufferedReader(new InputStreamReader(s.getInputStream()));//目的。Socket输出流。将大写数据写入到socket输出流,并发送给客户端。BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));// Printwriter既可以接受字节流也可以接受字符流,蓝牙替代红色部分  客户端也可以换//PrintWriter out = new Printwriter(s.getOutputStream(),true);String line = null;while((line = bufin.readLine()) != null)//要读到回车符或者换行符才能停止读!!!!,所以客户端要写newline1{System.out.println(line);//Out.println(line.toUppercase());  //上面写的参数是true,这里是有效刷新, //这个函数是自动刷新,替代红色部分   客户端也可以换bufout.write(line.toUpperCase());//也写缓冲区里bufout.newLine();//换行符,也就是结束标志readLine结束标记,否则客户端的readLine一直等bufout.flush();//写在缓冲区,要刷新}s.close();ss.close();}}

十一.网络编程 TCP-复制文件
实现:客户端发给服务端,然后在服务端保存起来

import java.io.*;import java.net.*;class InetTextDemo{public static void main(String[] args)throws Exception{Socket  s = new Socket("192.168.126.1",10006);//源BufferedReader bufr = new BufferedReader (new FileReader("E:\\hebing\\net.txt"));//目的BufferedWriter bufout = new BufferedWriter (new OutputStreamWriter(s.getOutputStream()));//PrintWriter out = new PrintWriter(s.getOutputStream(), true);//这个较为简单用这个//********************************代码1***********************************//代码1和代码2效果一样//接受服务端  欢迎光临的信息//InputStream in = s.getInputStream();//byte[] buf =new byte[1024];//int len = in.read(buf);//System.out.println(new String(buf, 0 , len));//BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));//String str = bufin.readLine();  //读socket流,因为服务端卡在while那,所以不会发数据给客户端,所以一直卡在这,两边都卡着//System.out.println(str);//********************************代码1************************************String line = null;while((line = bufr.readLine()) != null){bufout.write(line);bufout.newLine();bufout.flush();//out.println(line);}s.shutdownOutput();//关闭客户端的输出流。相当于给流中加入一个结束标记-1//********************************代码2***********************************////代码1和代码2效果一样//接受服务端  欢迎光临的信息//InputStream in = s.getInputStream();//byte[] buf =new byte[1024];//int len = in.read(buf);//System.out.println(new String(buf, 0 , len));BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));String str = bufin.readLine();  //读socket流,因为服务端卡在while那,所以不会发数据给客户端,所以一直卡在这,两边都卡着System.out.println(str);//********************************代码2************************************bufr.close();s.close();}}

import java.io.*;import java.net.*;//服务端class InetRece{public static void main(String[] args)throws Exception{ServerSocket ss = new ServerSocket(10006);//获取对象Socket s = ss.accept();//打印连接上的客户端String ip =s.getInetAddress().getHostAddress();System.out.println(ip+"...connected");//源BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));//目的BufferedWriter bufw = new BufferedWriter(new FileWriter("E:\\hebing\\servet.txt"));//PrintWriter out = new PrintWriter(new FileWriter("E:\\server.txt"),true);String line = null;//客户端把要复制的文件写到输出流中,没有给出结束标志,这里就一直在读读到文件末尾,也没读到换行符,所以又卡这里!!!!!!//上面的写到流中虽然写完了,但是往下走,又走到读取服务端”上传成功”的readLine卡在那了(按实际分析,放的位置不一定一样)//读取的文件中数据没有给结束符。while((line = bufin.readLine()) != null){bufw.write(line);bufw.newLine();bufw.flush();//out.println(line);}//写  欢迎使用BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));bufout.write("上传成功");bufout.flush(); //如果这里不写数据根本就没写进socket输出流中,导致对面一直在等//PrintWriter pw = new PrintWriter(s.getOutputStream(), true); //这种较为简便,以后是用这个//pw.println("上传成功");//out.close();bufw.close();s.close();ss.close();}}



0 0
原创粉丝点击