网络编程之应用

------- android培训java培训、期待与您交流! ----------

谈到应用,还是先从简单的开始

先介绍InetAddress和URL类

URL类:
类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
其实,它就是为我们提供切割URL字符串,为我们获取相应的URL信息
通过下面一段代码简单的说明其常用的功能:
import java.io.*;
import java.net.*;
public class URLDemo {
    /**
     * @param args
     */
    public static void main(String[] args)throws Exception{
        // TODO Auto-generated method stub
        URL url=new URL("Http://127.0.0.1:10004");//目标是我自己写的一个server
        System.out.println("File:"+url.getFile());// 获取此 URL 的文件名。
        System.out.println("getHost:"+url.getHost());//  获取此 URL 的主机名(如果适用)。
        System.out.println("getPath:"+url.getPath());//获取此 URL 的路径部分。
        System.out.println("getPort:"+url.getPort());//   获取此 URL 的端口号。 如果为默认端口,则返回-1,需要自己指定
        System.out.println("getProtocol:"+url.getProtocol());//    获取此 URL 的协议名称。
        System.out.println("getQuery:"+url.getQuery());//获取此 URL 的查询部分。
        URLConnection connection=url.openConnection();//建立连接,功能相当于socket,但是不同的是同工作在应用层,不用关闭链接
        InputStream is=connection.getInputStream();
        int len=0;
        byte[]bt=new byte[1024];
        while((len=is.read(bt))!=-1){
            System.out.println(new String(bt,0,len));
        }
        //InputStream iis=url.openStream();//其实它是URLConnection connection=url.openConnection();//建立连接,功能相当于socket,但是不同的是同工作在应用层,不用关闭链接
        //InputStream is=connection.getInputStream();其实它是这两者的总和
    }
}
输出结果:
File:/h.html?name=zhang
getHost:127.0.0.1
getPath:/h.html
getPort:10004
getProtocol:http
getQuery:name=zhang
Good,你好!我是曾
可以清楚看出每一部分的功能
有两个特殊的方法:openConnection(),此方法返回的是一个URLConnection类,表示和目标服务器建立连接,相当于完成Socket的三次握手,即连接工作;
但是和Socket不同的是,Socket工作在传输层,而它工作在用于层;它把Socket封装在自己类中;组装出自己的功能
另一个就是openStream()方法,此方法返回的是一个InputStream流对象,查看JDK文档,可以知道它就是URLConnection connection=url.openConnection();
InputStream is=connection.getInputStream();两者的组合;即url.openConnection().getInputStream();
基本情况就是这样;
InetAddress类
此类表示互联网协议 (IP) 地址。 简单的说它就代表IP地址对象,用来操作IP地址的,此类没有构造函数,只有通过自身的静态方法获取该类的对象;
一般而言,其方法为getbyXXX()基本就是返回其自身对象的。比如说:getAllByName();此方法返回的是一个InetAddress的数组;
因为同一个域名可能有多个IP地址;其它,就是getByAddress(),getByName();但有一个特殊的方法也是返回InetAddress,即getLocalHost();返回本地主机
接下来看段代码
public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        InetAddress ip=InetAddress.getByName("127.0.0.1");//因为InetAddress没有构造函数,只能通过调用自身静态方法产生
        System.out.println("address="+ip.getHostAddress());//获取主机地址
        System.out.println("name="+ip.getHostName());//获取主机名
        
    }
结果:
address=127.0.0.1
name=127.0.0.1//127.0.0.1是特殊的ip地址,用于测试本地主机
因为我的主机没有名,所以,用本地回环地址表示
还有一个常用的用法
String ip=dp.getAddress().getHostAddress();即InetAddress.getHostAddress()方法获取Ip字符串,注:dp.getAddress()返回的是一个InetAddress类。

使用UDP协议进行通信的网络应用,所涉及到的类有DatagramSocket类,InetAddress类

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

思路如下:

1.建立UDPSocket服务;

2.提供数据,并将数据封装到数据包中,注意:最终发送的都是字节流;

3.通过Socket服务的发送功能,将数据包发送出去;

4,关闭资源;

代码如下:

import java.net.*;
public class UdpSend {
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		//创建udp服务,通过DatagramSocket()对象
		DatagramSocket ds=new DatagramSocket();
		//确定存储数据的字节数组
		byte[]buf=new byte[1024];
		buf="我想了很久,一直都在等你".getBytes();
		//将数据封装为数据包,并指定目标Ip以及端口号
		DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10000);
		//发送数据
		ds.send(dp);
		//关闭资源
		ds.close();
		
	}

}

方式二:通过键盘录入数据

import java.io.*;
import java.net.*;
public class UdpSend2 {
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		DatagramSocket ds=new DatagramSocket();
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		String line=null;
		while((line=br.readLine())!=null){
			if("886".equals(line))break;
			byte[]bt=line.getBytes();
			DatagramPacket dp=new DatagramPacket(bt,0,bt.length,InetAddress.getByName("127.0.0.1"),10005);
			ds.send(dp);
		}
		ds.close();
	}

}
分别所对应的服务端

需求:
  定义一个应用程序,用于接收udp协议传输的数据并进行处理
 思路:
 1,定义udpsocket服务,并指定监听端口

2.定义一个数据包,因为要存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的
  不同数据信息
  3.通过socket服务的receive方法接收到的数据存入已经定义好的数据包中
  4.通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上
  5.关闭资源
 

import java.net.*;
public class UdpRece {

	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		//创建udp socket,建立端点
		DatagramSocket ds=new DatagramSocket(10000);//指定监听端口号
		byte[]buf=new byte[1024];//定义数据包,存储接收到的数据
		DatagramPacket dp=new DatagramPacket(buf,buf.length);//此构造方法用来接收数据,一共有两种构造方法用来接收,另一种DatagramPacket(byte[]by,ing offset,int length)
		ds.receive(dp);//通过receive方法接收到的数据存入数据包中,Receive方法为阻塞式方法
		String data=new String(dp.getData(),0,dp.getLength());//获取数据
		String data2=new String(buf,0,buf.length);
		String ip=dp.getAddress().getHostAddress();//获取源ip
		int port=dp.getPort();//获取源端口号
		System.out.println("data="+data+"ip="+ip+"port="+port+"data2="+data2);
		ds.close();//关闭资源
	}
}
方式二 
import java.io.*;
import java.net.*;
public class UdpRece2 {
    /**
     * @param args
     */
    public static void main(String[] args){
        // TODO Auto-generated method stub
        try{
        DatagramSocket ds=new DatagramSocket(10005);
        while(true){
        byte[]by=new byte[1024*64];
        DatagramPacket dp=new DatagramPacket(by,by.length);
        ds.receive(dp);
        String data=new String(dp.getData(),0,dp.getLength());
        String ip=dp.getAddress().getHostAddress();
        System.out.println("data="+data+"ip="+ip);
        }}
        catch(Exception e){
            e.printStackTrace();
        }
    }

}
有关TCP的应用

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

客户端代码:

import java.io.*;
import java.net.*;
public class TranceClient {
	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		try{
		Socket s=new Socket("127.0.0.1",10008);
		//定义读取键盘数据流对象
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		//定义目的,将数据写入socket输出流,发给服务器端
		//BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));第一种写法
		BufferedReader buf=new BufferedReader(new InputStreamReader(s.getInputStream()));
		//定义一个socket读取流,读取服务端返回的大写信息
		PrintWriter pw=new PrintWriter(s.getOutputStream(),true);//第二种写法
		String line=null;
		while((line=br.readLine())!=null){
			if("over".equals(line))break;
			//bw.write(line);第一种写法
			//bw.newLine();因为readline()的结束标记是以换行为标记的,所以必须得加
			//bw.flush();
			String str=buf.readLine();
			System.out.println("data="+str);
			pw.println(line);//第二种写法
		}
		br.close();
		s.close();}
		catch(Exception e){
			e.printStackTrace();
		}
	}

}

服务端代码:

import java.io.*;
import java.net.*;
public class TranceServer {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception{
        try{
        // TODO Auto-generated method stub
        ServerSocket st=new ServerSocket(10008);
        Socket s=st.accept();
        String ip=s.getInetAddress().getHostAddress();
        System.out.println("ip..."+ip+"....connection........");
        //读取socket读取流中的数据
        BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));//第一种写法
        //目的,socket输出流,将大写数据写入到socket输出流,并发送到客户端
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //PrintWriter bs=new PrintWriter(s.getOutputStream(),true);第二种写法
        String line=null;
        while((line=br.readLine())!=null){
            System.out.println(line);
            bw.write(line.toUpperCase());
            bw.newLine();
            bw.flush();
            //bs.println(line.toUpperCase());第二种写法
        }}
        catch(Exception e){
            e.printStackTrace();
        }
    }

}

简单聊天程序:采用了多线程编程思想:主程序:

import java.io.*;
import java.net.*;
public class ExchangeDemo {
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		DatagramSocket ds=new DatagramSocket();
		DatagramSocket dt=new DatagramSocket(10002);
		new Thread(new Send(ds)).start();
		new Thread(new Receve(dt)).start();
	}

}

客户端代码:


import java.io.*;
import java.net.*;
public class Receve implements Runnable {
    private DatagramSocket ds;
    Receve(DatagramSocket ds){
        this.ds=ds;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            try{
            byte[]b=new byte[1024*64];
            DatagramPacket dp=new DatagramPacket(b,0,b.length);
            ds.receive(dp);
            String data=new String(dp.getData(),0,dp.getLength());
            String ip=dp.getAddress().getHostAddress();
            System.out.println("data="+data+"ip="+ip);
            }catch(Exception e){
                throw new RuntimeException("运行失败");
            }
        }
    }

}

服务端代码:


import java.io.*;
import java.net.*;
public class Send implements Runnable{
private DatagramSocket ds;
Send(DatagramSocket ds){
this.ds=ds;
}
public void run(){
try{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null){
if("886".equals(line))break;
byte[]b=line.getBytes();
DatagramPacket dp=new DatagramPacket(b,0,b.length,InetAddress.getByName("127.0.0.1"),10002);
ds.send(dp);
}
ds.close();
}catch(Exception e){
throw new RuntimeException(运行出错!);
}
}
}

应用三:多线程上传图片客户端:

import java.io.*;
import java.net.*;
public class FilesClinetDemo {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		if(args.length!=1){
			System.out.println(" please choose a pic");
			return;
		}
		if(!args[0].endsWith(".jpg")){
			System.out.println("请上传一个jpg格式的图片!");
			return;
		}
		File f=new File(args[0]);
		if(!(f.exists()&&f.isFile())){
			System.out.println("请上传一个存在的文件!");
			return;
		}
		if(f.length()>1024*1024*5){
			System.out.println("请上传一个文件大小不超过5M的文件!");
			return;
		}
		try{
		Socket s=new Socket("127.0.0.1",10004);
		FileInputStream fs=new FileInputStream(f);
		OutputStream out=s.getOutputStream();
		InputStream in=s.getInputStream();
		byte[]bt=new byte[1024];
		int len=0;
		while((len=fs.read(bt))!=-1){
			out.write(bt,0,len);
		}
		s.shutdownOutput();
		int l=0;
		byte[]bb=new byte[1024];
		while((l=in.read(bb))!=-1){
			System.out.println(new String(bb,0,l));
		}
		s.close();
		fs.close();
		}catch(Exception e){
			throw new RuntimeException("上传文件失败");
		}
	}

}

服务器端:

import java.io.*;
import java.net.*;
public class PicThread implements Runnable {
	private Socket s;
	PicThread(Socket s){
		this.s=s;
	}
	@Override
	public void run(){
		// TODO Auto-generated method stub
		int count=1;
		String ip=s.getInetAddress().getHostAddress();
		System.out.println(ip+"......connection");
		try{
			File file=new File(ip+"("+count+")"+".jpg");
			while(file.exists())
				file=new File(ip+"("+(count++)+")"+".jpg");
		FileOutputStream fos=new FileOutputStream(file);
		InputStream is=s.getInputStream();
		OutputStream out=s.getOutputStream();
		int len=0;
		byte[]bt=new byte[1024];
		while((len=is.read(bt))!=-1){
			fos.write(bt,0,len);
		}
		out.write("上传成功".getBytes());
		s.close();
		fos.close();
		}
		catch(Exception e){
			throw new RuntimeException("上传失败!");
		}
	}

}

import java.io.*;
import java.net.*;
public class FilesServerDemo {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try{
        ServerSocket ss=new ServerSocket(10004);
        while(true){
            Socket s=ss.accept();
            new Thread(new PicThread(s)).start();
        }
        }catch(Exception e){
            throw new RuntimeException("上传失败");
        }
    }

}

应用三:上传文件,非多线程

/*
 * 上传文件客户端
 */
import java.io.*;
import java.net.*;
public class FileTraceClinetDemo {
	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		Socket s=new Socket("127.0.0.1",10009);
		BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
		BufferedReader bf=new BufferedReader(new InputStreamReader(new FileInputStream("D:\\Workspaces\\MyEclipse 10\\Day22\\src\\ExchangeDemo.java"),"gbk"));
		PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
		String line=null;
		while((line=bf.readLine())!=null){
			pw.println(line);
		}
		s.shutdownOutput();
		String answer=br.readLine();
		System.out.println(answer);
		s.close();
		bf.close();
	}

}

服务端:

/*
 * 上传文件服务端
 */
import java.io.*;
import java.net.*;
public class FileTraceServerDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		ServerSocket ss=new ServerSocket(10009);
		Socket s=ss.accept();
		String ip=s.getInetAddress().getHostAddress();
		System.out.println("connect......"+ip);
		BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:/ttt.txt"),"gbk"));
		BufferedWriter bb=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		String line=null;
		while((line=br.readLine())!=null){
			bw.write(line);
			bw.newLine();
		}
		bb.write("上传成功!");
		bb.newLine();
		bb.flush();
		s.close();
		bw.close();
	}

}

应用四:模仿Tomcat服务器

import java.io.*;
import java.net.*;
public class TomcatDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		ServerSocket st=new ServerSocket(10004);
		Socket sk=st.accept();//获取客户端的Socket
		InputStream is=sk.getInputStream();//获取输入流对象
		byte[]bs=new byte[1024];
		int len=is.read(bs);//读取数据
		String data=new String(bs,0,len);
		String ip=sk.getInetAddress().getHostAddress();
		System.out.println("ip......."+ip+'\n'+"data="+data);
		//BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(sk.getOutputStream(),"gbk"));
		OutputStream bw=sk.getOutputStream();
		bw.write("Good,你好!我是曾".getBytes());
		//bw.write("Good,你好!我是曾");
		//bw.flush();
		System.out.println("Good,你好!我是曾");
		sk.close();//关闭客户端Socket流
		st.close();
	}

}

其实,Tomcat服务器就是一个服务端的ServerSocket
应用五:采用了多线程

/*

 * 需求分析:
 * 客户端通过键盘录入用户名
 * 服务器对这个用户名进行校验
 * 如果该用户名存在,在服务器端显示xxx已经登录
 * 并在客户端显示xxx,欢迎光临
 * 如果该用户名不存在,在服务器端显示xxx尝试登录
 * 并在客户端显示xxx,该用户名不存在
 * 做多就登录三次
 */
客户端:

import java.io.*;
import java.net.*;
public class UserLoginClientDemo {
	public static void main(String[]args)throws Exception{
		Socket s=new Socket("127.0.0.1",10002);
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
		BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));
		for(int i=0;i<3;i++){
			String line=br.readLine();
			if(line==null)break;
			pw.println(line);
			String le=bufr.readLine();
			System.out.println(le);
			if(le.contains("欢迎")){
			break;
			}
		}
		s.close();
		br.close();
	}
}

服务端:

import java.io.*;
import java.net.*;
public class UserLoginThread implements Runnable {
	private Socket s;
	UserLoginThread(Socket s){
		this.s=s;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try{
			String ip=s.getInetAddress().getHostAddress();
			System.out.println(ip+".......connnection");
			for(int i=0;i<3;i++){
			BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
			String name=br.readLine();
			BufferedReader buf=new BufferedReader(new FileReader("user.txt"));
			BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			String line=null;
			boolean flag=false;
			while((line=buf.readLine())!=null){
				if(line.equals(name))
				{
					flag=true;
					break;
				}
			}
			if(flag){
				System.out.println(name+"欢迎,登录成功");
				bw.write(name+"欢迎,登录成功");
				bw.flush();
				break;
			}else{
				System.out.println(name+"登录未成功");
				bw.write(name+"登录未成功");
				bw.newLine();
				bw.flush();
			}
			}
			s.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}
import java.io.*;
import java.net.*;
public class UserLoginServerDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		ServerSocket ss=new ServerSocket(10002);
		while(true){
			Socket s=ss.accept();
			new Thread(new UserLoginThread(s)).start();
		}
	}

}

看了这么多例子,简短的总结下用JAVA编程对Tcp传输数据思路1.建立客户端的Socket对象,客户端连接到服务器2.服务器端:1,建立ServerSocket对象2.指定端口3.获取客户端Socket,通过accept()方法,注意此方法为阻塞式方法4.服务端关闭端口。其实,现实应用中,很多大型的公司都不会关闭服务端端口5.服务端没有专门的流对象,通过获取客户端的流对象进行操作。6.一般用到网络编程,都会用到IO流操作TCP和UDP基本情况就是这样;注意,Socket服务于传输层,建立连接,实际上是建立Socket流,而Socket流包括输入,输出流。


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值