一、TCP并发执行请求

一)图片上传:

第一、客户端:

1、创建服务端点

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

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

4、读取服务端反馈信息

5、关闭客户端

第二、服务端

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

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

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
2. import
3.   
4. class
5. {  
6. public static void main(String[] args) throws
7.     {  
8. //创建服务 
9. new Socket("192.168.1.101",10003);  
10. //读取键盘录入 
11.         BufferedReader bufr =   
12. new BufferedReader(new
13. new PrintWriter(s.getOutputStream(),true);  
14.         BufferedReader in =  
15. new BufferedReader(new
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
35. {  
36. private
37.     UserThread(Socket s)  
38.     {  
39. this.s = s;  
40.     }  
41. public void
42.     {  
43.         String ip = s.getInetAddress().getHostAddress();  
44. "........connected");  
45. try{  
46. //最多登陆三次 
47. for(int i=0;i<3;i++)  
48.             {  
49.                 BufferedReader in =  
50. new BufferedReader(new
51.                 String name = in.readLine();  
52. if(name==null)  
53. break;  
54.                   
55.                 BufferedReader bufr =  
56. new BufferedReader(new FileReader("user.txt"));  
57. new PrintWriter(s.getOutputStream(),true);  
58. null;  
59. boolean flag = false;  
60.   
61. while((line=bufr.readLine())!=null)  
62.                 {  
63. if(line.equals(name)){  
64. true;  
65. break;  
66.                     }  
67.                 }  
68. //对用户进行判断 
69. if(flag){  
70. ",已登录");  
71. "欢迎光临");  
72. break;  
73. else{  
74. ",尝试登陆");  
75. ",用户名不存在");  
76.                 }  
77.             }  
78.             s.close();  
79. catch
80. throw new RuntimeException(ip+"校验失败");  
81.         }  
82.     }  
83. }  
84. //创建服务端 
85. class
86. {  
87. public static void main(String[] args) throws
88.     {  
89. new ServerSocket(10003);  
90. //客户端并发访问 
91. while(true)  
92.         {  
93.             Socket s = ss.accept();  
94. new Thread(new
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
2. import
3. import
4. import
5.   
6. class
7. {  
8. //创建全局变量 
9. private
10. private
11. private
12. private
13.   
14. private
15. private
16. private
17.   
18. //构造函数,初始化窗体 
19.     MyIEGUI()  
20.     {  
21.         init();  
22.     }  
23. //创建窗体和组件,并将事件添加进来
24. public void
25.     {  
26. //设置窗体 
27. new Frame("my window");  
28. 300,200,600,500);  
29. new
30. //创建组件 
31. new Button("转到");  
32. new TextField(60);  
33. new TextArea(25,75);  
34.   
35. new Dialog(f,"提示信息-self",true);  
36. 300,100,300,150);  
37. new
38. new
39. 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. true);  
53.     }  
54. //常见引发的时间 
55. private void
56.     {  
57. //给but添加一个活动监听器
58. new
59.         {  
60. public void
61.             {  
62. try{  
63.                     showInfo();  
64. catch
65. throw new RuntimeException("客户端登陆失败");  
66.                 }  
67.         }});  
68. new
69.         {  
70. public void
71.             {  
72. false);  
73.             }  
74.         });  
75. //给文本框添加键盘事件
76. new
77.         {  
78. public void
79.             {  
80. try{  
81. if(e.getKeyCode()==KeyEvent.VK_ENTER)  
82.                         showInfo();  
83. catch
84. throw new RuntimeException("客户端登陆失败");  
85.                 }  
86.             }  
87.         });  
88. //关闭窗体事件 
89. new
90.         {  
91. public void
92.             {  
93. 0);  
94.             }  
95.         });  
96. new
97.         {  
98. public void
99.             {  
100. false);  
101.             }  
102.         });  
103.     }  
104. private void showInfo()throws
105.     {  
106.   
107. "");  
108. //获取路径 
109. //http://192.168.1.101:8080/myweb/myIE.html
110. //创建URL对象,解析路径 
111. new
112. //获取连接 
113.         URLConnection conn = url.openConnection();  
114. //获取输入流,读取获得的数据,并显示在文本框中
115.         InputStream in = conn.getInputStream();  
116. byte[] buf = new byte[1024];  
117. int
118. new String(buf,0,len));  
119.     }  
120. public static void
121.     {  
122. new
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();
	}
}