socket编程问题

clddcl 2013-01-01 08:35:19
一个简单实验,想做一个客户端向服务器端发送数字,服务器端向客户端返回此数字,只要客户端不输入0就一直往复,代码如下,但是运行后结果如下,估计是输入输出流的问题,本人菜鸟,望高手帮解答,感激不尽
服务器端代码:
import java.io.*;
import java.net.*;
public class Server {
private int port=8000;
private ServerSocket serverSocket;

public Server()throws IOException{
serverSocket=new ServerSocket(port);
System.out.println("服务器启动");
}
private PrintWriter getWriter(Socket socket)throws IOException{
OutputStream socketOut=socket.getOutputStream();
return new PrintWriter(socketOut,true);
}
private BufferedReader getReader(Socket socket)throws IOException{
InputStream socketIn=socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}

public void service(){
while(true){
Socket socket=null;
try{
socket=serverSocket.accept();
System.out.println("New connection accepted"+socket.getInetAddress()+":"+socket.getPort());
BufferedReader br=getReader(socket);
PrintWriter pw=getWriter(socket);

int a=0;
while((a=br.read())!=0){
System.out.println(a);
pw.println(a);
if(a==0)
break;
}
}catch(IOException e){
e.printStackTrace();
}finally{
try{
if(socket!=null)socket.close();
}catch(IOException e){e.printStackTrace();}
}
}
}
public static void main(String args[])throws IOException{
new Server().service();
}
}

客户端代码:
import java.io.*;
import java.net.*;
import java.util.*;
public class Client {
private String host="localhost";
private int port=8000;
private Socket socket;

public Client()throws IOException{
socket=new Socket(host,port);
}
public static void main(String args[])throws IOException{
new Client().talk();
}
private PrintWriter getWriter(Socket socket)throws IOException{
OutputStream socketOut=socket.getOutputStream();
return new PrintWriter(socketOut,true);
}
private BufferedReader getReader(Socket socket)throws IOException{
InputStream socketIn=socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}
public void talk()throws IOException{
try{
BufferedReader br=getReader(socket);
PrintWriter pw=getWriter(socket);
BufferedReader localReader=new BufferedReader(new InputStreamReader(System.in));
int a=0;
while((a=localReader.read())!=0){

pw.println(a);
System.out.println(br.read());

if(a==0)
break;
}
}catch(IOException e){
e.printStackTrace();
}finally{
try{socket.close();}catch(IOException e){e.printStackTrace();}
}
}
}

运行结果是下面这样,不知道为什么。。。

...全文
303 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
nmyangym 2013-01-04
  • 打赏
  • 举报
回复
楼主的代码,本来是收发都使用字符流了,(BufferedReader,PrinterWriter)。下面分析一下楼主看到的显示 内容: 1 client端从键盘读,是按字符读入的,a=localReader.read()这句读入的是字符的整数表示。 如输入1, (必须回车后,才能继续,否则阻塞)这时a是什么? a是字符'1'的整数表示。 '1'的ascii码是49, 所以 a是49。 2 按这个整数49,按字符方式输出,是怎么输出的? 从你的结果看,是按整数的各位的ascii码 输出的。 a的10位数是'4','4'的ascii码为52,先输出,所以在服务器端看到了这个数 52. a的个位数是'9','9'的ascii码为57,随着输出,这时服务器端看到了这个数 57。 3 楼主的PrinterWriter对象是带刷新缓冲的,(return new PrintWriter(socketOut,true);), 所以当'49'这个整数输出完后,要跟着回车和换行这两个字符,它们的整数表示是'13','10'. 所以在服务器端看到了 这两个数。 4 整数'49'输出后,还有两个回车换行符,也要输出,回车符'13',按上面步骤 2 的方式,输 出49和51,在服务器端看到这两个数。 5 象上面步骤 3 一样,后面是13,10。 6 '13'输出后,最后输出'10',就是'49','48', 跟着'13','10'. 7 这就是服务器端看到的情况。看看客户端输出的情况,客户端接手服务器端发回的内容。 服务器端第一个接收到的字符是'4',其整数形式是52,按上面 步骤 2 ,服务器发回其各 位的整数表示,52的十位是'5',其ascci码为'53',首先把这个发回,所以客户端最先接收 到'53'. 而个位的2的ascii码为50,所以看到了'50'这个数。 8 和步骤3一样,服务器端也是带自动刷新缓冲的,看到了这个'13'. 9 其实,客户端的缓冲区里,还有很多字符,但代码只有在发送时才接收一次,所以返回的 内容没有接收完。 以上是本人的笨拙的分析,表达的不是很好,供楼主参考,本人认为根本的原因是: 1 楼主用字符流发送整数,造成的。2 客户端接收受发送限制,(不能完全接收),这个最好用一个线程来完成,楼主可以慢慢改进。 楼主可以把客户端和服务器端改一下,看看与原来的不同的效果。 附上代码(没有别的修改,只是做了char类型转换):

//客户端
    public void talk()throws IOException{
        try{
            BufferedReader br=getReader(socket);
            PrintWriter pw=getWriter(socket);
            BufferedReader localReader=new BufferedReader(new InputStreamReader(System.in));
            int a=0;
            while((a=localReader.read())!='0'){
                 
                pw.println((char)a);// 以字符方式发送
                System.out.println((char)br.read());//以字符方式显示
                 
                if(a=='0')
                    break;
            }
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            try{socket.close();}catch(IOException e){e.printStackTrace();}
        }
    }

//服务器端
   public void service(){
        while(true){
            Socket socket=null;
            try{
                socket=serverSocket.accept();
                System.out.println("New connection accepted"+socket.getInetAddress()+":"+socket.getPort());
                BufferedReader br=getReader(socket);
                PrintWriter pw=getWriter(socket);
                 
                int a=0;
                while((a=br.read())!='0'){
                    System.out.println((char)a);//以字符方式显示
                    pw.println((char)a);//以字符方式发送
                    if(a=='0')
                        break;
                }
            }catch(IOException e){
                e.printStackTrace();
            }finally{
                try{
                    if(socket!=null)socket.close();
                }catch(IOException e){e.printStackTrace();}
            }
        }
    }
clddcl 2013-01-04
  • 打赏
  • 举报
回复
引用 8 楼 nmyangym 的回复:
楼主的代码,本来是收发都使用字符流了,(BufferedReader,PrinterWriter)。下面分析一下楼主看到的显示 内容: 1 client端从键盘读,是按字符读入的,a=localReader.read()这句读入的是字符的整数表示。 如输入1, (必须回车后,才能继续,否则阻塞)这时a是什么? a是字符'1'的整数表示……
怒赞!
nmyangym 2013-01-03
  • 打赏
  • 举报
回复
用readLine()读入字符串形式,测试可以的。楼主参考一下:

//--------------------------服务器端 service方法
//--------------------------
    public void service(){
        while(true){
            Socket socket=null;
            try{
                socket=serverSocket.accept();
                System.out.println("New connection accepted"+socket.getInetAddress()+":"+socket.getPort());
                BufferedReader br=getReader(socket);
                PrintWriter pw=getWriter(socket);

                String s=null;				//按行读字符串.
                while(!(s=br.readLine()).equals("0")){
                    System.out.println(s);
                    pw.println(s);
                }
		break;//退出外层循环。接收到"0"结束。
            }catch(IOException e){
                e.printStackTrace();
            }finally{
                try{
                    if(socket!=null)socket.close();
                }catch(IOException e){e.printStackTrace();}
            }
        }
    }

//---------------- 客户端talk()方法
//----------------
    public void talk()throws IOException{
        try{
            BufferedReader br=getReader(socket);
            PrintWriter pw=getWriter(socket);
            BufferedReader localReader=new BufferedReader(new InputStreamReader(System.in));
            //int a=0;
            String s=null;				//按字符串读入,发送.
	    while(!(s=localReader.readLine()).equals("0")){
                System.out.println("----s is  "+s); 
                pw.println(s);
                System.out.println(br.readLine());	//按字符串接收.
            }
            pw.println(s);//键盘输入"0",输出后程序退出。
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            try{socket.close();}catch(IOException e){e.printStackTrace();}
        }
    }
clddcl 2013-01-03
  • 打赏
  • 举报
回复
引用 6 楼 nmyangym 的回复:
用readLine()读入字符串形式,测试可以的。楼主参考一下: Java code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748//--------------------------服务器端 service方法//------------……
非常感谢!!!请问这是什么问题呢???
abc41106 2013-01-02
  • 打赏
  • 举报
回复
引用 4 楼 clddcl 的回复:
引用 2 楼 eviljordan 的回复: 试试readLine()或者用DataInputStream或DataOutputStream你说的方法我都试过,都有问题,达不到我要的效果。。。
DataInputStream 可以实现的。给你个例子看看。跟你的功能差不多。 http://download.csdn.net/detail/abc41106/4873560 这个是java大学教程的随书实例源码。
clddcl 2013-01-02
  • 打赏
  • 举报
回复
引用 2 楼 eviljordan 的回复:
试试readLine()或者用DataInputStream或DataOutputStream
你说的方法我都试过,都有问题,达不到我要的效果。。。
clddcl 2013-01-02
  • 打赏
  • 举报
回复
引用 1 楼 abc41106 的回复:
BufferedReader的read()一次只读一个字节。 完成这个功能,你还是用readLine(),然后Integer.parseInt()转换吧。
谢谢,我试下
eviljordan 2013-01-01
  • 打赏
  • 举报
回复
试试readLine()或者用DataInputStream或DataOutputStream
abc41106 2013-01-01
  • 打赏
  • 举报
回复
BufferedReader的read()一次只读一个字节。 完成这个功能,你还是用readLine(),然后Integer.parseInt()转换吧。

51,410

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧