黑马程序员————自定义客户端服务器出现的错误

来源:互联网 发布: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流的时候一定要注意阻塞式方法的结束标记。

0 0