黑马程序员————自定义客户端服务器出现的错误
来源:互联网 发布:js prototype知乎 编辑:程序博客网 时间:2024/06/14 12:17
------ android培训、java培训、期待与您交流! ----------
学到网络编程,自定义了一个服务端和客户端,出现了两个小问题,在这里记录一下。
1.用浏览器客户端访问自定义的服务器出现的问题:
自定义的服务器代码如下
package com.itheimaexercise.day24;
import java.io.*;
import java.net.*;
public class ServerTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(8977);
}
catch(IOException e){
e.printStackTrace();
}
Socket clientSocket = null;
try{
clientSocket = serverSocket.accept();
}
catch(IOException e){
e.printStackTrace();
}
String ip = clientSocket.getInetAddress().getHostAddress();
System.out.println(ip+"......connected");
//看看浏览器客户端访问服务器的时候都说了什么:
BufferedInputStream bufIn = null;
try{
bufIn = new BufferedInputStream(clientSocket.getInputStream());
}
catch(IOException e){
e.printStackTrace();
}
byte[] buf = new byte[1024];
int len = 0;
try{
while((len=bufIn.read(buf))!=-1){
System.out.println(new String(buf,0,len));
System.out.println();
System.out.println(new String(buf,0,len));
}
catch(IOException e){
e.printStackTrace();
}
BufferedWriter bufOut = null;
try{
bufOut = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
}
catch(IOException e){
e.printStackTrace();
}
try{
bufOut.write("<font color='red' size=6>欢迎你客户端");
bufOut.newLine();
bufOut.flush();
}
catch(IOException e){
e.printStackTrace();
}
finally{
try{
clientSocket.close();
}
catch(IOException e){
e.printStackTrace();
}
}
}
}
打开服务器后在浏览器地址栏输入 http://10.127.0.16:8977 后,服务器控制台出现如下信息:
10.127.0.16......connected
GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)
Accept-Encoding: gzip, deflate
Host: 10.127.0.16:8977
DNT: 1
Connection: Keep-Alive
而浏览器却一直处于等待状态
无法显示服务器发送的信息
说明程序卡在了某个地方,也就是所谓的阻塞了,程序无法往下执行,只能一直等待。
经过分析,代码中只有bufIn.read(buf)是阻塞式方法,程序应该是卡在这里了。
我在while中定义了 len=bufIn.read(buf)!=-1 的条件,但是客户端发来的请求消息头并没有read方法能够识别的结束标记,read方法找不到结束的那个点,只好一直等在那里,所以,不应该用len=bufIn.read(buf)!=-1作为判断的条件
经过调整,把服务器读取浏览器消息头的代码改成如下:
byte[] buf = new byte[1024];
int len = 0;
try{
//浏览器发来的消息没有结束标记,会阻塞!不能用-1判断了
len = bufIn.read(buf);
System.out.println(new String(buf,0,len));
}
catch(IOException e){
e.printStackTrace();
}
再运行,浏览器就出现了服务器发送的信息了:
————————————————————————
2.用自定义的客户端,访问Tomcat服务器中网页出现的问题:
需求:用自定义的客户端访问Tomcat myweb下的demo.html,将其内容展示在控制台上
自定义客户端代码如下:
package com.itheimaexercise.day24;
import java.net.*;
import java.io.*;
//自定义一个浏览器访问Tomcat服务器
public class ClientTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Socket clientSocket = null;
try{
clientSocket = new Socket("10.127.0.16",8080);
}
catch(IOException e){
e.printStackTrace();
}
BufferedWriter bufOut = null;
BufferedReader bufIn = null;
try{
bufOut = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
bufIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch(IOException e){
e.printStackTrace();
}
try{
bufOut.write("GET /myweb/demo.html HTTP/1.1");
bufOut.write("Accept: */*");
bufOut.write("Accept-Language: zh-cn");
bufOut.write("Host: 10.127.0.16:8977");
bufOut.write("Connection: Alive");
bufOut.newLine();
bufOut.newLine();
bufOut.flush();
}
catch(IOException e){
e.printStackTrace();
}
String line = null;
try{
while((line=bufIn.readLine())!=null){
System.out.println(line);
}
}
catch(IOException e){
e.printStackTrace();
}
finally{
try{
clientSocket.close();
}
catch(IOException e){
e.printStackTrace();
}
}
}
}
运行后出现如下信息:
HTTP/1.1 505 HTTP Version Not Supported
Server: Apache-Coyote/1.1
Date: Tue, 28 Apr 2015 07:10:23 GMT
Connection: close
很郁闷,因为跟老师写的一样,怎么出现不支持HTTP协议呢,并且原来从浏览器客户端是可以访问的啊
后来发现应该是在写请求消息头的时候出现了问题,
用write方法写的没有换行,而HTTP协议的消息头应该是一行一行的,
于是将请求消息头改成了:
try{
bufOut.write("GET /myweb/demo.html HTTP/1.1");
bufOut.newLine();
bufOut.write("Accept: */*");
bufOut.newLine();
bufOut.write("Accept-Language: zh-cn");
bufOut.newLine();
bufOut.write("Host: 10.127.0.16:8977");
bufOut.newLine();
bufOut.write("Connection: Alive");
bufOut.newLine();
bufOut.newLine();
bufOut.flush();
}
catch(IOException e){
e.printStackTrace();
}
再重新运行就OK了,搞定。
总结,在用到IO流的时候一定要注意阻塞式方法的结束标记。
- 黑马程序员————自定义客户端服务器出现的错误
- 黑马程序员——使用TCP协议完成一个客户端一个服务器。客户端从键盘输入读取一个字符串,发送到服务器。 服务器接收客户端发送的字符串,反转之后发回客户端。客户端接收并打印。
- 黑马程序员 【】java学习之路——TCP(三)客户端上传文件到服务器
- 黑马程序员——TCP并发,浏览器客户端与Tomcat服务器
- 黑马程序员—TreeMap练习-字母出现的次数
- 【黑马程序员】视频拓展——多线程聊天室客户端与客户端的交互
- 黑马程序员——自定义异常类
- 黑马程序员——day16自定义标签
- 黑马程序员——自定义异常
- 黑马程序员——自定义异常
- 黑马程序员——ArrayList去除自定义对象的重复
- 黑马程序员——Tomcat服务器原理的小例子
- 黑马程序员——错误汇总
- 黑马程序员 JavaScript 容易出现的错误
- 服务器配置——常常出现的错误
- 黑马程序员————java中基于tcp模拟多客户端上次图片到服务器
- 黑马程序员——TCP客户端,服务端介绍
- 黑马程序员——TCP客户端,服务端互相发送信息
- 再看设计模式——观察者模式
- v4l2_i2c_new_subdev_board接口分析(侧重I2C设备的探测)
- BroadcastReceiver(二)手动注册注销receiver
- 理解std::move
- 引导层
- 黑马程序员————自定义客户端服务器出现的错误
- iOS绘图教程
- 判断一个数是否是素数
- Eclipse 导入已有Java工程或项目
- SoapUI压力测试的指标项说明
- memcpy和memmove区别和实现
- C++类内定义静态变量
- ACM搜索算法总结
- 自定义View之音量图