黑马程序员 基础 网络编程应用

 ------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

一、TCP并发执行请求

一)图片上传:

第一、客户端:

1、创建服务端点

2、读取客户端以后图片数据

3、通过Socket输出流将数据发给服务端

4、读取服务端反馈信息

5、关闭客户端

第二、服务端

对于客户端并发上传图片,服务端如果单纯的使用while(true)循环式有局限性的,当A客户端连接上以后,被服务端获取到,服务端执行具体的流程,这时B客户端连接就只有等待了,因为服务端还未处理完A客户端的请求,还有循环来回执行下须accept方法,所以暂时获取不到B客户端对象,那么为了可让多个客户端同时并发访问服务端,那么服务端最好就是将每个客户端封装到一个单独的线程,这样就可以同时处理多个客户端的请求。如何定义线程呢?只要明确每个客户端要在服务端执行的代码即可,将改代码存入到run方法中。 毕老师的代码:

  1. import java.io.*;  
  2. import java.net.*;  
  3.   
  4.   
  5. //客户端   
  6. class UploadClient   
  7. {  
  8.     public static void main(String[] args)   
  9.     {  
  10.         //判断上传的文件是否符合要求   
  11.         if(args.length!=1)  
  12.         {  
  13.             System.out.println("请选择一个jpg格式的图片");  
  14.             return ;  
  15.         }  
  16.         File file = null;  
  17.         try{  
  18.             file = new File(args[0]);  
  19.             if(!(file.exists() && file.isFile()))  
  20.             {  
  21.                 System.out.println("该文件有问题,要么补存在,要么不是文件");  
  22.                 return ;  
  23.             }  
  24.   
  25.             if(!file.getName().endsWith(".jpg"))  
  26.             {  
  27.                 System.out.println("图片格式错误,请重新选择");  
  28.                 return ;  
  29.             }  
  30.             if(file.length()>1024*1024*5)  
  31.             {  
  32.                 System.out.println("文件过大,没安好心");  
  33.                 return ;  
  34.             }  
  35.         }catch (Exception e){  
  36.             throw new RuntimeException("获取文件失败");  
  37.         }  
  38.         //创建客户端,接收客户端流对象   
  39.         Socket s = null;  
  40.         FileInputStream fis = null;  
  41.         try{  
  42.             s = new Socket("192.168.1.101",10003);  
  43.             fis = new FileInputStream(file);  
  44.             OutputStream out = s.getOutputStream();  
  45.             //将数据写入到读取流中,传送给服务端  
  46.             byte[] b = new byte[1024];  
  47.             int len = 0;  
  48.             while((len=fis.read(b))!=-1)  
  49.             {  
  50.                 out.write(b,0,len);  
  51.             }  
  52.             s.shutdownOutput();  
  53.             //获取服务端反馈的信息  
  54.             InputStream in = s.getInputStream();  
  55.             byte[] by = new byte[1024];  
  56.             int n = in.read(by);  
  57.             System.out.println(new String(by,0,n));  
  58.   
  59.         }catch (IOException e){  
  60.             throw new RuntimeException("服务创建或读取流失败");  
  61.         }  
  62.         finally{  
  63.             try{  
  64.                 if(fis!=null)  
  65.                     fis.close();  
  66.             }catch (IOException e){  
  67.                 throw new RuntimeException("读取流关闭失败");  
  68.             }  
  69.             try{  
  70.                 if(s!=null)  
  71.                     s.close();  
  72.             }catch (IOException e){  
  73.                 throw new RuntimeException("资源关闭失败");  
  74.             }  
  75.         }  
  76.     }  
  77. }  
  78.   
  79. //服务端   
  80. //创建服务端多线程   
  81. class ServerThread implements Runnable  
  82. {  
  83.     private Socket s;  
  84.     ServerThread(Socket s)  
  85.     {  
  86.         this.s = s;  
  87.     }  
  88.     public void run()  
  89.     {  
  90.         //获取客户端的ip   
  91.         int count = 1;  
  92.         String ip = s.getInetAddress().getHostAddress();  
  93.         System.out.println(ip+"...connected");  
  94.         FileOutputStream fos = null;  
  95.         try{  
  96.             //获取客户端数据,判断文件是否重名  
  97.             InputStream in = s.getInputStream();  
  98.             File dir = new File("D:\\File\\pics");  
  99.             File file = new File(dir,ip+".jpg");  
  100.             while(file.exists())  
  101.                 file = new File(dir,ip+"("+(count++)+").jpg");  
  102.             //将数据写入到指定文件中   
  103.             fos = new FileOutputStream(file);  
  104.             byte[] b = new byte[1024];  
  105.             int len = 0;  
  106.             while((len=in.read(b))!=-1)  
  107.             {  
  108.                 fos.write(b,0,len);  
  109.             }  
  110.             //将信息反馈给客户端   
  111.             OutputStream out = s.getOutputStream();  
  112.             out.write("上传成功".getBytes());  
  113.         }catch (Exception e){  
  114.             throw new RuntimeException(ip+"上传失败");  
  115.         }  
  116.         finally{  
  117.             try{  
  118.                 if(fos!=null)  
  119.                     fos.close();  
  120.             }catch (IOException e){  
  121.                 throw new RuntimeException("写入流关闭失败");  
  122.             }  
  123.             try{  
  124.                 if(s!=null)  
  125.                     s.close();  
  126.             }catch (IOException e){  
  127.                 throw new RuntimeException("资源关闭失败");  
  128.             }  
  129.         }  
  130.     }  
  131. }  
  132.   
  133. //服务端   
  134. class UploadServer  
  135. {  
  136.     public static void main(String[] args)   
  137.     {  
  138.         ServerSocket ss = null;  
  139.         Socket s = null;  
  140.         try{  
  141.             //创建服务端,并接受多个客户端并发访问  
  142.             ss = new ServerSocket(10003);  
  143.             while(true)  
  144.             {  
  145.                 s = ss.accept();  
  146.                 new Thread(new ServerThread(s)).start();  
  147.             }  
  148.         }catch (IOException e){  
  149.             throw new RuntimeException("上传失败");  
  150.         }  
  151.           
  152.         finally{  
  153.             try{  
  154.                 if(s!=null)  
  155.                     s.close();  
  156.             }catch (IOException e){  
  157.                 throw new RuntimeException("资源关闭失败");  
  158.             }  
  159.         }  
  160.     }  
  161. }  
import java.io.*;
import java.net.*;


//客户端
class UploadClient 
{
	public static void main(String[] args) 
	{
		//判断上传的文件是否符合要求
		if(args.length!=1)
		{
			System.out.println("请选择一个jpg格式的图片");
			return ;
		}
		File file = null;
		try{
			file = new File(args[0]);
			if(!(file.exists() && file.isFile()))
			{
				System.out.println("该文件有问题,要么补存在,要么不是文件");
				return ;
			}

			if(!file.getName().endsWith(".jpg"))
			{
				System.out.println("图片格式错误,请重新选择");
				return ;
			}
			if(file.length()>1024*1024*5)
			{
				System.out.println("文件过大,没安好心");
				return ;
			}
		}catch (Exception e){
			throw new RuntimeException("获取文件失败");
		}
		//创建客户端,接收客户端流对象
		Socket s = null;
		FileInputStream fis = null;
		try{
			s = new Socket("192.168.1.101",10003);
			fis = new FileInputStream(file);
			OutputStream out = s.getOutputStream();
			//将数据写入到读取流中,传送给服务端
			byte[] b = new byte[1024];
			int len = 0;
			while((len=fis.read(b))!=-1)
			{
				out.write(b,0,len);
			}
			s.shutdownOutput();
			//获取服务端反馈的信息
			InputStream in = s.getInputStream();
			byte[] by = new byte[1024];
			int n = in.read(by);
			System.out.println(new String(by,0,n));

		}catch (IOException e){
			throw new RuntimeException("服务创建或读取流失败");
		}
		finally{
			try{
				if(fis!=null)
					fis.close();
			}catch (IOException e){
				throw new RuntimeException("读取流关闭失败");
			}
			try{
				if(s!=null)
					s.close();
			}catch (IOException e){
				throw new RuntimeException("资源关闭失败");
			}
		}
	}
}

//服务端
//创建服务端多线程
class ServerThread implements Runnable
{
	private Socket s;
	ServerThread(Socket s)
	{
		this.s = s;
	}
	public void run()
	{
		//获取客户端的ip
		int count = 1;
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"...connected");
		FileOutputStream fos = null;
		try{
			//获取客户端数据,判断文件是否重名
			InputStream in = s.getInputStream();
			File dir = new File("D:\\File\\pics");
			File file = new File(dir,ip+".jpg");
			while(file.exists())
				file = new File(dir,ip+"("+(count++)+").jpg");
			//将数据写入到指定文件中
			fos = new FileOutputStream(file);
			byte[] b = new byte[1024];
			int len = 0;
			while((len=in.read(b))!=-1)
			{
				fos.write(b,0,len);
			}
			//将信息反馈给客户端
			OutputStream out = s.getOutputStream();
			out.write("上传成功".getBytes());
		}catch (Exception e){
			throw new RuntimeException(ip+"上传失败");
		}
		finally{
			try{
				if(fos!=null)
					fos.close();
			}catch (IOException e){
				throw new RuntimeException("写入流关闭失败");
			}
			try{
				if(s!=null)
					s.close();
			}catch (IOException e){
				throw new RuntimeException("资源关闭失败");
			}
		}
	}
}

//服务端
class UploadServer
{
	public static void main(String[] args) 
	{
		ServerSocket ss = null;
		Socket s = null;
		try{
			//创建服务端,并接受多个客户端并发访问
			ss = new ServerSocket(10003);
			while(true)
			{
				s = ss.accept();
				new Thread(new ServerThread(s)).start();
			}
		}catch (IOException e){
			throw new RuntimeException("上传失败");
		}
		
		finally{
			try{
				if(s!=null)
					s.close();
			}catch (IOException e){
				throw new RuntimeException("资源关闭失败");
			}
		}
	}
}

二)客户端并发登陆:

客户端通过键盘录入用户名。服务端对这个用户名进行校验。如果该用户存在,在服务端显示xxx,已登陆。并在客户端显示 xxx,欢迎光临。如果该用户存在,在服务端显示xxx,尝试登陆。并在客户端显示 xxx,该用户不存在。最多就登录三次。

  1. import java.io.*;  
  2. import java.net.*;  
  3.   
  4. class LoginClient   
  5. {  
  6.     public static void main(String[] args) throws Exception  
  7.     {  
  8.         //创建服务   
  9.         Socket s = new Socket("192.168.1.101",10003);  
  10.         //读取键盘录入   
  11.         BufferedReader bufr =   
  12.             new BufferedReader(new InputStreamReader(System.in));  
  13.         PrintWriter out = new PrintWriter(s.getOutputStream(),true);  
  14.         BufferedReader in =  
  15.             new BufferedReader(new InputStreamReader(s.getInputStream()));  
  16.         //最多三次登陆   
  17.         for(int i=0;i<3;i++)  
  18.         {  
  19.             String line = bufr.readLine();  
  20.             if(line==null)  
  21.                 break;  
  22.             out.println(line);  
  23.             String info = in.readLine();  
  24.             System.out.println(info);  
  25.             if(info.contains("欢迎"))  
  26.                 break;  
  27.         }  
  28.         //关闭流资源   
  29.         bufr.close();  
  30.         s.close();  
  31.     }  
  32. }  
  33. //服务端的多线程,使服务端共享  
  34. class UserThread implements Runnable  
  35. {  
  36.     private Socket s;  
  37.     UserThread(Socket s)  
  38.     {  
  39.         this.s = s;  
  40.     }  
  41.     public void run()  
  42.     {  
  43.         String ip = s.getInetAddress().getHostAddress();  
  44.         System.out.println(ip+"........connected");  
  45.         try{  
  46.             //最多登陆三次   
  47.             for(int i=0;i<3;i++)  
  48.             {  
  49.                 BufferedReader in =  
  50.                     new BufferedReader(new InputStreamReader(s.getInputStream()));  
  51.                 String name = in.readLine();  
  52.                 if(name==null)  
  53.                     break;  
  54.                   
  55.                 BufferedReader bufr =  
  56.                     new BufferedReader(new FileReader("user.txt"));  
  57.                 PrintWriter out = new PrintWriter(s.getOutputStream(),true);  
  58.                 String line = null;  
  59.                 boolean flag = false;  
  60.   
  61.                 while((line=bufr.readLine())!=null)  
  62.                 {  
  63.                     if(line.equals(name)){  
  64.                         flag = true;  
  65.                         break;  
  66.                     }  
  67.                 }  
  68.                 //对用户进行判断   
  69.                 if(flag){  
  70.                     System.out.println(name+",已登录");  
  71.                     out.println(name+"欢迎光临");  
  72.                     break;  
  73.                 }else{  
  74.                     System.out.println(name+",尝试登陆");  
  75.                     out.println(name+",用户名不存在");  
  76.                 }  
  77.             }  
  78.             s.close();  
  79.         }catch (Exception e){  
  80.             throw new RuntimeException(ip+"校验失败");  
  81.         }  
  82.     }  
  83. }  
  84. //创建服务端   
  85. class LoginServer  
  86. {  
  87.     public static void main(String[] args) throws Exception  
  88.     {  
  89.         ServerSocket ss = new ServerSocket(10003);  
  90.         //客户端并发访问   
  91.         while(true)  
  92.         {  
  93.             Socket s = ss.accept();  
  94.             new Thread(new UserThread(s)).start();  
  95.         }  
  96.     }  
  97. }  
import java.io.*;
import java.net.*;

class LoginClient 
{
	public static void main(String[] args) throws Exception
	{
		//创建服务
		Socket s = new Socket("192.168.1.101",10003);
		//读取键盘录入
		BufferedReader bufr = 
			new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		BufferedReader in =
			new BufferedReader(new InputStreamReader(s.getInputStream()));
		//最多三次登陆
		for(int i=0;i<3;i++)
		{
			String line = bufr.readLine();
			if(line==null)
				break;
			out.println(line);
			String info = in.readLine();
			System.out.println(info);
			if(info.contains("欢迎"))
				break;
		}
		//关闭流资源
		bufr.close();
		s.close();
	}
}
//服务端的多线程,使服务端共享
class UserThread implements Runnable
{
	private Socket s;
	UserThread(Socket s)
	{
		this.s = s;
	}
	public void run()
	{
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"........connected");
		try{
			//最多登陆三次
			for(int i=0;i<3;i++)
			{
				BufferedReader in =
					new BufferedReader(new InputStreamReader(s.getInputStream()));
				String name = in.readLine();
				if(name==null)
					break;
				
				BufferedReader bufr =
					new BufferedReader(new FileReader("user.txt"));
				PrintWriter out = new PrintWriter(s.getOutputStream(),true);
				String line = null;
				boolean flag = false;

				while((line=bufr.readLine())!=null)
				{
					if(line.equals(name)){
						flag = true;
						break;
					}
				}
				//对用户进行判断
				if(flag){
					System.out.println(name+",已登录");
					out.println(name+"欢迎光临");
					break;
				}else{
					System.out.println(name+",尝试登陆");
					out.println(name+",用户名不存在");
				}
			}
			s.close();
		}catch (Exception e){
			throw new RuntimeException(ip+"校验失败");
		}
	}
}
//创建服务端
class LoginServer
{
	public static void main(String[] args) throws Exception
	{
		ServerSocket ss = new ServerSocket(10003);
		//客户端并发访问
		while(true)
		{
			Socket s = ss.accept();
			new Thread(new UserThread(s)).start();
		}
	}
}
二、客户端和服务的浏览器演示:

浏览器是一个标准的客户端,它可以对服务端传送过来的数据消息进行解析,把符合应用层协议的消息部分解析后,将头信息拆包掉,传送到应用层,只保留了正确的正文主题部分显示在主题部分上。

而由于使用java编译是在传输层和网际层处理的,所以,会接受到全部的消息,包含了头消息。而浏览器处于应用层,已将发送来的头消息去除,只留下了主体信息。

三、URL和URLConnection

一)URL:

URI:范围更大,条形码也包含于此范围

URL:范围较小,即域名

1、方法:

1)构造函数:URL(String protocol,String host,int port,String file)

---> 依protocol,host,port,file创建URL对象

2)String getProtocol()  --->  获取协议

3)String getHost()     --->  获取主机名

4)int getPort()        --->  获取端口号

5)String getFile()     --->  获取URL文件名

6)String getPath()     ---> 获取此URL的路径部分

7)String getQuery()   ---->  获取此URL的查询部,客户端传输的特定信息

2、一般输入网址,是不带端口号的,此时可进行设置,在URL中写port,若port为-1,则分配一个默认的80端口,否则用自己定义的,如

int port = getPort();

if(port == -1)

 port = 80;

二)URLConnection:

1、方法:

1)URLConnection openConnection() --->  表示到URL所引用的远程对象的链接

2)InputStream getInputStream():获取输入流

3)OutputStream getOutputStream():获取输出流

 

示例:

  1. import java.awt.*;  
  2. import java.awt.event.*;  
  3. import java.net.*;  
  4. import java.io.*;  
  5.   
  6. class MyIEGUI  
  7. {  
  8.     //创建全局变量   
  9.     private Frame f;  
  10.     private Button but;  
  11.     private TextField tf;  
  12.     private TextArea ta;  
  13.   
  14.     private Dialog d;  
  15.     private Label lab;  
  16.     private Button okBut;  
  17.   
  18.     //构造函数,初始化窗体   
  19.     MyIEGUI()  
  20.     {  
  21.         init();  
  22.     }  
  23.     //创建窗体和组件,并将事件添加进来  
  24.     public void init()  
  25.     {  
  26.         //设置窗体   
  27.         f = new Frame("my window");  
  28.         f.setBounds(300,200,600,500);  
  29.         f.setLayout(new FlowLayout());  
  30.         //创建组件   
  31.         but = new Button("转到");  
  32.         tf = new TextField(60);  
  33.         ta = new TextArea(25,75);  
  34.   
  35.         d = new Dialog(f,"提示信息-self",true);  
  36.         d.setBounds(300,100,300,150);  
  37.         d.setLayout(new FlowLayout());  
  38.         lab = new Label();  
  39.         okBut = new Button("确定");  
  40.   
  41.         //将组件添加到窗体  
  42.         f.add(tf);  
  43.         f.add(but);  
  44.         f.add(ta);  
  45.           
  46.         d.add(lab);  
  47.         d.add(okBut);  
  48.   
  49.         //添加事件  
  50.         myEvent();  
  51.         //设置窗体可见  
  52.         f.setVisible(true);  
  53.     }  
  54.     //常见引发的时间   
  55.     private void myEvent()  
  56.     {  
  57.         //给but添加一个活动监听器  
  58.         but.addActionListener(new ActionListener()  
  59.         {  
  60.             public void actionPerformed(ActionEvent e)  
  61.             {  
  62.                 try{  
  63.                     showInfo();  
  64.                 }catch (Exception ex){  
  65.                     throw new RuntimeException("客户端登陆失败");  
  66.                 }  
  67.         }});  
  68.         okBut.addActionListener(new ActionListener()  
  69.         {  
  70.             public void actionPerformed(ActionEvent e)  
  71.             {  
  72.                 d.setVisible(false);  
  73.             }  
  74.         });  
  75.         //给文本框添加键盘事件  
  76.         tf.addKeyListener(new KeyAdapter()  
  77.         {  
  78.             public void keyPressed(KeyEvent e)  
  79.             {  
  80.                 try{  
  81.                     if(e.getKeyCode()==KeyEvent.VK_ENTER)  
  82.                         showInfo();  
  83.                 }catch (Exception ex){  
  84.                     throw new RuntimeException("客户端登陆失败");  
  85.                 }  
  86.             }  
  87.         });  
  88.         //关闭窗体事件   
  89.         f.addWindowListener(new WindowAdapter()  
  90.         {  
  91.             public void windowClosing(WindowEvent e)  
  92.             {  
  93.                 System.exit(0);  
  94.             }  
  95.         });  
  96.         d.addWindowListener(new WindowAdapter()  
  97.         {  
  98.             public void windowClosing(WindowEvent e)  
  99.             {  
  100.                 d.setVisible(false);  
  101.             }  
  102.         });  
  103.     }  
  104.     private void showInfo()throws Exception  
  105.     {  
  106.   
  107.         ta.setText("");  
  108.         //获取路径   
  109.         String urlPath = tf.getText();//http://192.168.1.101:8080/myweb/myIE.html  
  110.         //创建URL对象,解析路径   
  111.         URL url = new URL(urlPath);  
  112.         //获取连接   
  113.         URLConnection conn = url.openConnection();  
  114.         //获取输入流,读取获得的数据,并显示在文本框中  
  115.         InputStream in = conn.getInputStream();  
  116.         byte[] buf = new byte[1024];  
  117.         int len=in.read();  
  118.         ta.setText(new String(buf,0,len));  
  119.     }  
  120.     public static void main(String[] args)   
  121.     {  
  122.         new MyIEGUI();  
  123.     }  
  124. }  
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

class MyIEGUI
{
	//创建全局变量
	private Frame f;
	private Button but;
	private TextField tf;
	private TextArea ta;

	private Dialog d;
	private Label lab;
	private Button okBut;

	//构造函数,初始化窗体
	MyIEGUI()
	{
		init();
	}
	//创建窗体和组件,并将事件添加进来
	public void init()
	{
		//设置窗体
		f = new Frame("my window");
		f.setBounds(300,200,600,500);
		f.setLayout(new FlowLayout());
		//创建组件
		but = new Button("转到");
		tf = new TextField(60);
		ta = new TextArea(25,75);

		d = new Dialog(f,"提示信息-self",true);
		d.setBounds(300,100,300,150);
		d.setLayout(new FlowLayout());
		lab = new Label();
		okBut = new Button("确定");

		//将组件添加到窗体
		f.add(tf);
		f.add(but);
		f.add(ta);
		
		d.add(lab);
		d.add(okBut);

		//添加事件
		myEvent();
		//设置窗体可见
		f.setVisible(true);
	}
	//常见引发的时间
	private void myEvent()
	{
		//给but添加一个活动监听器
		but.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				try{
					showInfo();
				}catch (Exception ex){
					throw new RuntimeException("客户端登陆失败");
				}
		}});
		okBut.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				d.setVisible(false);
			}
		});
		//给文本框添加键盘事件
		tf.addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				try{
					if(e.getKeyCode()==KeyEvent.VK_ENTER)
						showInfo();
				}catch (Exception ex){
					throw new RuntimeException("客户端登陆失败");
				}
			}
		});
		//关闭窗体事件
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		d.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				d.setVisible(false);
			}
		});
	}
	private void showInfo()throws Exception
	{

		ta.setText("");
		//获取路径
		String urlPath = tf.getText();//http://192.168.1.101:8080/myweb/myIE.html
		//创建URL对象,解析路径
		URL url = new URL(urlPath);
		//获取连接
		URLConnection conn = url.openConnection();
		//获取输入流,读取获得的数据,并显示在文本框中
		InputStream in = conn.getInputStream();
		byte[] buf = new byte[1024];
		int len=in.read();
		ta.setText(new String(buf,0,len));
	}
	public static void main(String[] args) 
	{
		new MyIEGUI();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值