java网络编程
2016-09-20 21:43
253 查看
一.网络编程概述
1.计算机网络
(1).性质:独立功能多台计算机及其外部设备 连接起来 实现资源共享和信息传递2.网络编程
(1).性质:就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换二.网络模型
一般是指OSI参考模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 TCP/IP参考模型 应用层 传输层 网际层 主机至网络层
网络应用程序:网络编程 IO流 多线程组成
网络编程三要素:
A:ip地址
B:端口
C:协议
1.ip地址
(1).性质: 网络中计算机的唯一标识。计算机只能识别二进制的数据,所有我们的ip地址应该是一个二进制的数据,但是呢,我们配置的ip地址的确不是二进制的,为什么呢?ip:10.98.87.74 换算:1010 1100010 1010111 1001010 假如真是:1010 1100010 1010111 1001010 我们要配置ip地址 记忆起来比较麻烦 所以 我们就把ip地址的每个字节上的数据换算成十进制 然后用.分开 "点分十进制"
(2).ip的组成:网络号段+主机号段
(3).ip的分类:
A类 1.0.0.1–127.255.255.254 10.X.X.X是私有地址(私有地址就是在互联网上不
使用,而被用在局域网上)
B类 128.0.0.1–191.255.255.254 172.16.0.0–172.31.255.255是私有地址
C类 192.0.0.1–223.255.255.254 192.168.X.X是私有地址 169.254.X.X是保留地址
D类 224.0.0.1–239.255.255.254
E类 240.0.0.1–247.255.255.254
(4).ip的数量
A类:第一号段位网络号段+后三段的主机号段一个网络号:256*256*256 = 1677 7216
B类:前二号段位网络号段+后二段的主机号段一个网络号:256*256 = 65536
C类:前三号段位网络号段+后一段的主机号段一个网络号:256
(5).两个DOS命令
A.ipconfig:查看本机ip地址
B.ping:后面跟ip地址 测试本机与指定的ip地址间的通信是否有问题
(6).特殊的ip地址
127.0.0.1 回环地址(表示本机) x.x.x.255 广播地址 x.x.x.0 网络地址
(7).端口号
A.性质
正在运行的程序的标识
物理端口
逻辑端口
A.每个网络程序都会至少有一个逻辑端口
B.用于标识进程的逻辑地址 不同进程的标识
C.有效端口0~65535 其中0-1024系统使用或保留端口
注意:一般建议使用1W以上的
(8).协议
A.UDP
i.把数据打包 ii.数据有限制(不能超过64k) iii.不建立连接 iiii.速度快 iiiii.不可靠
B.TCP(三次握手协议)
i.建立连接通道 ii.数据无限制 iii.速度慢 iiii.可靠
C.UDP和TCP的分别
举例 UDP:发短信 TCP:打电话
2.Socket(网络套接字)
(1).性质Socket编程,网络编程,套接字编程
Socket包含了:ip地址+端口
Socket原理机制:
通信的两端都是Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
三.InetAddress类
查看API发现此类并没有构造方法。那么什么情况下的类是没有构造方法的?一般有三种情况
1.什么情况下的类是没有构造方法的
(1).成员方法全部都是静态方法的(2).单例设计模式(Runtime)
(3).类中有静态方法返回该类的对象(InetAddress)
2.常用方法
(1).public static InetAddress getByName(String host)根据主机名或者IP地址的字符串表示得到IP地址对象
(2).public String getHostName()
获取主机名
(3).public String getHostAddress()
获取ip地址
四.UDP传输数据
1. UDP协议发送数据
(1).步骤A.创建发送端Socket对象 DatagramSocket
B.创建数据,并把数据打包 DatagramPacket(byte[] buf,int length,InetAddress,int port)
C.调用Socket对象的发送方法发送数据包 public void send(DatagramPacket p)
D.释放资源 close()
(2).代码实现
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class sendDemo { public static void main(String[] args) throws IOException{ //A.创建发送端Socket对象 DatagramSocket dSocket=new DatagramSocket(); //要发送的数据 byte [] buf="hello".getBytes(); //B.把数据打包 DatagramPacket dPacket=new DatagramPacket(buf,buf.length,InetAddress.getByName("10.98.87.74"),12345); //C.发送数据包 dSocket.send(dPacket); //D.释放资源 dSocket.close(); } }
2. UDP协议接收数据
(1).步骤A.创建接收端Socket对象 DatagramSocket(int port) 在UDP协议中 类DatagramSocket不仅是创建发送对象 也是创建接收数据对象
B.创建一个数据包(接收容器) DatagramPacket(byte [] buf,int length)
C.调用Socket对象的接收方法接收数据包 public void receive(DategramPacket p)//阻塞
D.解析数据,并显示在控制台
public byte[] getData():获取数据缓冲区
public int getLength():获取数据的实际长度
E.释放资源 close()
(2).代码实现
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class receiveDemo { public static void main(String[] args) throws IOException{ //A.创建接收端Socket对象 注意此处构造方法是发送端的端口 DatagramSocket dSocket=new DatagramSocket(12345); byte [] buf=new byte[1024]; //B.创建一个数据包 接收容器 DatagramPacket dPacket=new DatagramPacket(buf,buf.length); //C.调用Socket对象的接收方法接收数据包 dSocket.receive(dPacket); //D.解析数据 转换成字符串 String string=new String(dPacket.getData(),0,dPacket.getLength()); //输出在控制台 System.out.println(string); //E.释放资源 dSocket.close(); } }
此时就可以用这两段代码实现数据传输接收 但必须接收方先打开
但是以上的代码只能实现一个消息的传输 那么怎么让输入的消息传输?
此时接收端应该一直开着等待接收数据,是不需要关闭的 所有要用while(true)
而发送端则是一直发数据 实现代码如下:
(3).封装键盘录入数据
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class SendDemo { public static void main(String[] args) throws IOException{ DatagramSocket dSocket=new DatagramSocket(); BufferedReader br=new BufferedReader(new InputStreamReader(System.in));//输入 String line=null; while((line=br.readLine())!=null){ if("EXIT".equals(line)){//输入EXIT发送端结束 break; } byte [] buf=line.getBytes(); int length=buf.length; DatagramPacket dPacket=new DatagramPacket(buf, length, InetAddress.getByName("10.98.87.74"),12345);//封装 dSocket.send(dPacket);//发送方法 } dSocket.close();//关闭 } }
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class receiveDemo { public static void main(String[] args) throws IOException{ DatagramSocket dSocket=new DatagramSocket(12345);//端口 while(true){ byte [] bys=new byte[1024]; DatagramPacket dPacket=new DatagramPacket(bys,bys.length);//封装 dSocket.receive(dPacket); String string=new String(dPacket.getData(),0,dPacket.getLength());//转换成字符串 String ip=dPacket.getAddress().getHostAddress();//获取传送端的ip System.out.println(ip+":"+string); } } }
改写成多线程如下:
(4).多线程UDP
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class Entry { public static void main(String[] args) throws IOException{ DatagramSocket dSocket=new DatagramSocket();//创建发送端对象 DatagramSocket dSocket2=new DatagramSocket(12308);//创建接收端对象 SendThread st=new SendThread(dSocket); ReceiveThread rt=new ReceiveThread(dSocket2); Thread t1=new Thread(st); Thread t2=new Thread(rt); t1.start(); t2.start(); } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class SendThread implements Runnable { private DatagramSocket ds; public SendThread(DatagramSocket ds) { this.ds=ds; } @Override public void run() { try{ BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String line=null; while((line=br.readLine())!=null){ if("EXIT".equals(line)){ break; } byte [] buf=line.getBytes(); int length=buf.length; DatagramPacket dPacket=new DatagramPacket(buf, length, InetAddress.getByName("10.98.87.74"),12308); ds.send(dPacket); } ds.close(); } catch (IOException e) { e.printStackTrace(); } } }
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ReceiveThread implements Runnable { private DatagramSocket ds; public ReceiveThread(DatagramSocket ds) { this.ds=ds; } @Override public void run() { try { while(true){ byte [] bys=new byte[1024]; DatagramPacket dPacket=new DatagramPacket(bys,bys.length); ds.receive(dPacket); String string=new String(dPacket.getData(),0,dPacket.getLength()); String ip=dPacket.getAddress().getHostAddress(); System.out.println(ip+":"+string); } } catch (IOException e) { e.printStackTrace(); } } }
五.TCP传输数据
1. TCP协议发送数据
(1).步骤A.创建发送端的Socket对象 这一步如果成功 就说明连接已经建立成功了
Socket(InetAddress address,int port)
Socket(String host,int port)
B.获取输出流,写数据
C.释放资源
(2).代码实现
public class ClientDemo { public static void main(String[] args) throws IOException{ Socket s=new Socket(InetAddress.getByName("10.98.87.74"),12345); byte [] bys="12345".getBytes(); OutputStream os=s.getOutputStream();//输出流 os.write(bys); os.close();//关闭 s.close();//关闭 } }
2. TCP协议接收数据
(1).步骤A.创建接收端的Socket对象 ServerSocket(int port)
B.监听客户端连接。返回一个对应的Socket对象 public Socket accept()
C.获取输入流,读取数据显示在控制条 InputStream is=s.getInputStream() is.read(bys);//阻塞方法
D.释放资源
(2).代码实现
public class SeverDemo { public static void main(String[] args) throws IOException{ ServerSocket s=new ServerSocket(12345);//接收数据 接口 Socket ss=s.accept();//阻塞方法 InputStream is=ss.getInputStream();//输入流 byte [] bys=new byte[1024]; int length=is.read(bys); String string=new String(bys,0,length); System.out.println(string); ss.close(); } }
注意:TCP协议一定要先开服务器 要保证数据一定要收到
3.封装键盘录入数据
public class ClientDemo { public static void main(String[] args) throws IOException{ Socket s=new Socket(InetAddress.getByName("10.98.87.74"),12345); BufferedReader br=new BufferedReader( new InputStreamReader(System.in)); OutputStream os=s.getOutputStream(); String line=null; while((line=br.readLine())!=null) { os.write(line.getBytes()); } s.close(); } }
public class SeverDemo { public static void main(String[] args) throws IOException{ ServerSocket s=new ServerSocket(12345); Socket ss=s.accept(); while(true) { InputStream is=ss.getInputStream(); byte [] bys=new byte[1024]; int length=is.read(bys); String string=new String(bys,0,length); String ip=ss.getInetAddress().getHostAddress(); System.out.println(ip+":"+string); } } }
4.TCP实现数据传输并写入文档中
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; public class ClientDemo { public static void main(String[] args) throws IOException{ Socket s=new Socket("10.98.87.74",12345); BufferedReader br=new BufferedReader( new InputStreamReader(System.in)); BufferedWriter bw=new BufferedWriter( new OutputStreamWriter(s.getOutputStream()));//转换成字符流 String line=null; while((line=br.readLine())!=null) { if(line.endsWith("888")){ break; } bw.write(line); bw.newLine(); bw.flush();//刷新 } br.close(); s.close(); } }
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class ServerDemo { public static void main(String[] args) throws IOException{ ServerSocket ss=new ServerSocket(12345); Socket s=ss.accept(); BufferedReader br=new BufferedReader( new InputStreamReader(s.getInputStream()));//转换字符流 BufferedWriter bw=new BufferedWriter(new FileWriter("c.txt")); String line=null; while((line=br.readLine())!=null){ String ip=s.getInetAddress().getHostAddress(); bw.write(ip+":"+line); bw.newLine(); bw.flush(); } } }
5.TCP实现读取文档中的数据进行传输并输出于控制台
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.Socket; public class ClientDemo { public static void main(String[] args) throws IOException{ Socket s=new Socket("10.98.87.74",12345); BufferedReader br=new BufferedReader(new FileReader("c.txt"));//读取c.txt BufferedWriter bw=new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); String line=null; while((line=br.readLine())!=null) { bw.write(line); bw.newLine(); bw.flush(); } br.close(); s.close(); } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class ServerDemo { public static void main(String[] args) throws IOException{ ServerSocket ss=new ServerSocket(12345); Socket s=ss.accept(); BufferedReader br=new BufferedReader( new InputStreamReader(s.getInputStream())); String line=null; while((line=br.readLine())!=null){ System.out.println(line); } } }
6.TCP实现读取文档中的数据进行传输并写入另一文档中
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.Socket; public class ClientDemo { public static void main(String[] args) throws IOException{ Socket s=new Socket("10.98.87.74",12345); BufferedReader br=new BufferedReader(new FileReader("c.txt")); BufferedWriter bw=new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); String line=null; while((line=br.readLine())!=null) { bw.write(line); bw.newLine(); bw.flush(); } br.close(); s.close(); } }
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class ServerDemo { public static void main(String[] args) throws IOException{ ServerSocket ss=new ServerSocket(12345); Socket s=ss.accept(); BufferedReader br=new BufferedReader( new InputStreamReader(s.getInputStream())); BufferedWriter bw=new BufferedWriter(new FileWriter("d.txt")); String line=null; while((line=br.readLine())!=null){ bw.write(line); bw.newLine(); bw.flush(); } } }
7.TCP实现读取文档中的数据进行传输并写入另一文档中并且控制台有提示
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; public class ClientDemo { public static void main(String[] args) throws IOException{ Socket s=new Socket("10.98.87.74",12345); BufferedReader br=new BufferedReader(new FileReader("c.txt")); BufferedWriter bw=new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); String line=null; while((line=br.readLine())!=null) { bw.write(line); bw.newLine(); bw.flush(); } BufferedReader br2=new BufferedReader( new InputStreamReader(s.getInputStream())); String li=br2.readLine(); System.out.println(li); br.close(); s.close(); } } import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class ServerDemo { public static void main(String[] args) throws IOException{ ServerSocket ss=new ServerSocket(12345); Socket s=ss.accept(); BufferedReader br=new BufferedReader( new InputStreamReader(s.getInputStream())); BufferedWriter bw=new BufferedWriter(new FileWriter("f.txt")); String line=null; while((line=br.readLine())!=null){ bw.write(line); bw.newLine(); bw.flush(); } BufferedWriter bw2=new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); bw2.write("传输完成"); bw2.newLine(); bw2.flush(); } } //我们发现这样写 文件传输完后 控制台也是没有输出数据
怎样解决?
有两种解决方式!
(1).第一种就是在服务端中
while((line=br.readLine())!=null){ if(line.endsWith("***")){//***为文档中最后一行内容 break; } bw.write(line); bw.newLine(); bw.flush(); }//因为阻塞的方式才让个数据传输完 但还是无法再控制台中打印 这样就可以解决 但这样解决有个漏洞 假如文档其他内容有这个内容 那么就会出现问题 所以就会出现第2种方式解决
(2).public void shutdownOutput() java提供的一类解决的方法
public class ClientDemo { public static void main(String[] args) throws IOException{ Socket s=new Socket("10.98.87.74",12345); BufferedReader br=new BufferedReader(new FileReader("c.txt")); BufferedWriter bw=new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); String line=null; while((line=br.readLine())!=null) { bw.write(line); bw.newLine(); bw.flush(); } s.shutdownOutput();//当发送完数据就禁止输出流 BufferedReader br2=new BufferedReader( new InputStreamReader(s.getInputStream())); String li=br2.readLine(); System.out.println(li); br.close(); s.close(); } } import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class ServerDemo { public static void main(String[] args) throws IOException{ ServerSocket ss=new ServerSocket(12345); Socket s=ss.accept(); BufferedReader br=new BufferedReader( new InputStreamReader(s.getInputStream())); BufferedWriter bw=new BufferedWriter(new FileWriter("f.txt")); String line=null; while((line=br.readLine())!=null){ bw.write(line); bw.newLine(); bw.flush(); } BufferedWriter bw2=new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); bw2.write("传输完成"); bw2.newLine(); bw2.flush(); } }
这样就解决了无法在控制台打印的问题
8.TCP实现图片的发送
注意这个地方要改用字节流了public class ClientDemo { public static void main(String[] args) throws IOException{ Socket s=new Socket(InetAddress.getByName("10.98.87.74"),12345); BufferedInputStream bi=new BufferedInputStream( new FileInputStream("1.png")); BufferedOutputStream os=new BufferedOutputStream(s.getOutputStream()); byte [] bys=new byte[2048]; int length=0; while((length=bi.read(bys))!=-1){ os.write(bys,0,length); os.flush(); } s.shutdownOutput(); InputStream is=s.getInputStream(); byte [] by=new byte[1024]; int len=is.read(by); String string=new String(by,0,len); System.out.println(string); bi.close(); s.close(); } }
public class ServerDemo { public static void main(String[] args) throws IOException{ ServerSocket ss=new ServerSocket(12345); Socket s=ss.accept(); BufferedInputStream is=new BufferedInputStream(s.getInputStream()); BufferedOutputStream os=new BufferedOutputStream( new FileOutputStream("2.png")); byte [] bys=new byte[2048]; int length=0; while((length=is.read(bys))!=-1){ os.write(bys,0,length); os.flush(); } OutputStream oss=s.getOutputStream(); oss.write("传送完成".getBytes()); os.close(); s.close(); } }
相关文章推荐