<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

        明月松間照 清泉石上流


                                            ——— 兵臨城下   貓科動物
    posts - 70, comments - 137, trackbacks - 0, articles - 23
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    一個關(guān)于Java Socket的問題,大家看一下

    Posted on 2006-04-29 17:05 兵臨城下 閱讀(5356) 評論(9)  編輯  收藏 所屬分類: J2SE

    一個關(guān)于Java Socket的問題,大家看一下:
    我的目的是從client端發(fā)出一段字符串,server端接收后原樣返回給客戶端。
    客戶端:ConnClient? 服務(wù)器端ConnSerer(完整源代碼附在最后)

    ===client端===
    建了一個out流和in流:
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    ??
    PrintWriter Clientout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);

    向server端輸出:clientOut.println("hello");? clientout.close();
    等待服務(wù)器端返回代碼片段:
    StringBuffer sbuf = new StringBuffer();
    char[] buff = new char[10];
    ??
    int iLen = in.read(buff);
    ??
    while (iLen>0) {?
    ?? sbuf.append(buff,0,iLen);
    ?? if (sbuf.toString().trim().equals("hello")){
    ?????? System.out.println(sbuf.toString());
    ??????? break;
    ?? }
    ??? iLen = in.read(buff);
    }

    ?


    ===server端===
    同樣建了一個in流和out流
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    ??
    PrintWriter Serverout = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);

    接收client端信息和原樣返回信息:
    StringBuffer sbuf = new StringBuffer();
    ????
    char[] buff = new char[10];
    int iLen = in.read(buff);
    ?????????
    while(iLen>0){?
    ?sbuf.append(buff,0,iLen);
    ?if (sbuf.toString().trim().equals("hello")){
    ?
    ?System.out.println("Echoing: " + sbuf.toString());
    ?serverout.println(sbuf.toString());?????? //此處為server端輸出流,返回給client端
    ?break;
    ??????? }

    ?iLen = in.read(buff);
    }


    問題來了:
    1、如果按以上代碼運(yùn)行,server端可以收到client的信息,但client端卻收不到返回的信息。為什么?
    2、后來我把client端的clientout.close()注釋掉后,一切正常,client端能收到server端返回的信息。這又為什么?
    難道server端和client端用的是一個out流?為什么client端把out流關(guān)掉后(clientout.close()),server端就不能返回信息呢?

    以我以前的理解,server端和client端建的兩個輸出流應(yīng)該是獨(dú)立的。不會因為我把client端的out流關(guān)掉后,server端out流就不能返回了?不會吧!呵呵!


    還有一個問題:server端怎么判斷client端數(shù)據(jù)已經(jīng)發(fā)送完畢?
    一開始,我用clientout.print("hello"),運(yùn)行后,server端顯示已經(jīng)連接成功但一直偵聽,沒有收到信息,認(rèn)為client端還沒有發(fā)送完成。
    后來,我改用clientout.println("hello"),運(yùn)行后,一切正常,服務(wù)器端也收到信息(hello)。
    從上看出server的地判定就是一個回車符,不知道這樣認(rèn)識對不對?大家指點(diǎn)!
    經(jīng)過我試驗,如果client端print后,用clientout.close()也可以使server端接收到信息。但卻不能返回信息。也就是我發(fā)現(xiàn)上面說述的問題來由。

    以上幾個問題,請大家和banq大哥多加指點(diǎn)!

    源代碼如下:
    client端:
    package com.socket;

    import java.net.*;
    import java.io.*;

    public class ConnClient {
    ? public static void main(String[] args) throws IOException {

    ?InetAddress addr = InetAddress.getByName(null);
    ?
    ?System.out.println("addr = " + addr);
    ?
    ?Socket socket = new Socket(addr, 8080);
    ?//socket.setSoTimeout(5000);
    ?
    ?try {
    ?? System.out.println("socket = " + socket);
    ?? BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    ??
    ?? PrintWriter clientout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
    ??
    ?? String strSend = "hello";
    ??
    ? ?
    ?? clientout.println(strSend);
    ?? //clientout.println("\r\n");
    ?? //clientout.println();
    ?? //clientout.close();
    ?? StringBuffer sbuf = new StringBuffer();
    ??
    ?char[] buff = new char[10];
    ??
    ?int iLen = in.read(buff);
    ??
    ?while (iLen>0) {?
    ??sbuf.append(buff,0,iLen);
    ??if (sbuf.toString().trim().equals(strSend)){
    ???System.out.println(sbuf.toString());
    ????? break;
    ???? }
    ?? iLen = in.read(buff);
    ?}
    ?
    ?}catch(Exception e){
    ??e.printStackTrace();
    ?} finally {
    ?? System.out.println("closing...");
    ?? socket.close();
    ?}
    ?
    }
    }


    server端代碼:
    package com.socket;
    import java.io.*;
    import java.net.*;

    public class ConnServer {?
    ?
    ? public static final int PORT = 8080;
    ? public static void main(String[] args) throws IOException {

    ?ServerSocket s = new ServerSocket(PORT);
    ?System.out.println("Started: " + s);
    ?try {
    ?? Socket socket = s.accept();
    ?? try {
    ?System.out.println("Connection accepted: "+ socket);
    ?BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    ?PrintWriter serverout = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
    ??
    ????? StringBuffer sbuf = new StringBuffer();
    ???????
    ?char[] buff = new char[10];
    ?iLen = in.read(buff);
    ?????????
    ?while(iLen>0){?
    ?sbuf.append(buff,0,iLen);
    ?if(sbuf.toString().trim().equals("hello")){
    ?
    ?System.out.println("Echoing: " + sbuf.toString());
    ?serverout.println(sbuf.toString());
    ??????? }
    ?????????? iLen = in.read(buff);
    }??
    ?? }catch(Exception e) { e.printStackTrace();}
    ??? finally {
    ???System.out.println("closing...");
    ???
    ???socket.close();
    ?? }
    ?
    ?} finally {
    ?? s.close();
    ?}
    ? }
    }


    評論

    # re: 一個關(guān)于Java Socket的問題,大家看一下  回復(fù)  更多評論   

    2006-05-02 17:45 by 兵臨城下
    經(jīng)過幾天的調(diào)試,初步有點(diǎn)心得,在我的blog上記錄一下:
    1、client端,clientout.close()語句表面上只是關(guān)閉了socket輸出流,但從我的調(diào)試中發(fā)現(xiàn),在關(guān)閉這個out流后,client就不能在取得socket,說明在關(guān)閉out流的同時,也隱式的關(guān)閉了socket。所以server端就無法返回數(shù)據(jù)了。解釋我的第一和第二個問題。
    2、關(guān)于server端判定client端是否信息發(fā)送完畢的信號問題。
    從我?guī)滋斓恼{(diào)試中,我總結(jié)出幾點(diǎn)(可能還有其他的,請補(bǔ)充):
    a、就是經(jīng)常使用的out.println(out.print不行)
    b、那就是關(guān)閉client端out流,out.close()。但這種方法卻關(guān)閉了socket,顯然不是大家所愿的。

    # re: 一個關(guān)于Java Socket的問題,大家看一下  回復(fù)  更多評論   

    2006-05-08 13:49 by 兵臨城下
    問題進(jìn)行中……(實時紀(jì)錄)
    考慮到字節(jié)流的需要,在client端和server端都改用字節(jié)流DataInputStream和DataOutputStream,相應(yīng)的輸出方法使用out.write(byte[]) 。
    問題一:此種輸入輸出流沒有了out.println()方法,該怎么判定client端輸出流的結(jié)束??
    問題二:在client端,發(fā)送的信息的源分為兩種,字符串和文件流。兩種不同的輸入流在server端接收判斷結(jié)束時是否存在區(qū)別??

    對于問題二,筆者有一些心得:
    server端的接收代碼段是:
    byte[] sbyte = new byte[1024];
    int len;
    while((len = in.read(sbyte)) != -1) {
    out.write(sbyte,0,len);
    out.flush();
    }

    如果client端輸入流為字符串,server端在接收完畢后,在while語句中不能正常跳出。而使用文件流時就可以跳出循環(huán)。

    以上問題歡迎大家發(fā)表意見!

    # re: 一個關(guān)于Java Socket的問題,大家看一下  回復(fù)  更多評論   

    2006-05-08 21:12 by 兵臨城下
    更正一下,上面所說的文件流能順利跳出循環(huán)不正確,其實不然。
    實際上在client端傳輸完成后,server端while循環(huán)還是不能跳出,最后能夠完整輸出實際是在客戶端強(qiáng)制關(guān)閉socket后,server端while才跳出循環(huán)的。
    從以上我總結(jié)出,不管是字符流,還是文件流,都得附加一個標(biāo)示符來標(biāo)識client端傳輸?shù)慕Y(jié)束。

    # re: 一個關(guān)于Java Socket的問題,大家看一下  回復(fù)  更多評論   

    2006-05-12 12:19 by 兵臨城下
    又獲益頗多啊!
    再來說說這幾天的心得:
    關(guān)于這個socket,折騰了好幾天了啊!
    出現(xiàn)這個問題的初衷是:公司內(nèi)想要實現(xiàn)java和C++的socket通訊。

    關(guān)于這個java端(也就是client端)發(fā)送信息結(jié)束的判定問題總結(jié)如下:
    如果server端也是java程序(C++我不是很了解),而且server端使用一個while循環(huán)讀取數(shù)據(jù)時(類似于while((len = in.read(sbyte)) != -1) {}),即使client端發(fā)送完成,即while((len = inFile.read(bb)) != -1) {}循環(huán)語句跳出后,server端仍然在while語句中,不能正常跳出。因為server端認(rèn)為你沒有發(fā)送結(jié)束。
    究其原因,我認(rèn)為,因為在java socket中對于socket的input和output流結(jié)束,有一個socket方法來給出結(jié)束的標(biāo)志:socket.shutdownOutput();socket.shutdownInput();

    這兩個方法為java socket判定client端發(fā)送結(jié)束的標(biāo)志。

    當(dāng)然如果和我上述留言中所說的,使用特定設(shè)置的標(biāo)志符當(dāng)然是可以的。

    # re: 一個關(guān)于Java Socket的問題,大家看一下[未登錄]  回復(fù)  更多評論   

    2009-02-28 22:11 by sunshine
    如果通信協(xié)議用的是java默認(rèn)的編碼格式,客戶端還是用BufferedReader.readline()方法,這個是以\r\n為界定符的。在你從socket產(chǎn)生bufferedReader的時候,PrintWriter clientout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true)最后一個boolean標(biāo)志是否在println()方法中自動調(diào)用outputstream.flush()把緩存的東西是否發(fā)送出去。否則還要自己再調(diào)用PrintWriter.flush()發(fā)送。而且這個println()后在你的數(shù)據(jù)后加上\r\n,用客戶端的readline()正好可以讀到你的數(shù)據(jù),當(dāng)然是去掉了\r\n.

    如果你要使用自己的界定符,就不能使用BufferedReader,應(yīng)該使用它的基類,在while(in.ready())循環(huán)中inputstream.read(),然后自己斷開你的數(shù)據(jù)。這和串口的通信是一樣。既然是輸入流,當(dāng)然收到是連續(xù)的字節(jié)數(shù)據(jù),除非你制定一個界定符,否則系統(tǒng)怎么知道你發(fā)送完了?同時,還要注意發(fā)送字節(jié)的時候,兩端的編碼格式要一致。

    # 回答得太好了  回復(fù)  更多評論   

    2009-06-27 21:20 by 周小兵
    哥們,你回答的太好了,這正是我遇到的問題,問題都和你一樣的,我在看你的回答前,我已經(jīng)測試過,找到了問題的原因,上網(wǎng)驗證發(fā)現(xiàn)你回答的和我測試的一樣。有緣多多交流啊,QQ:379172684。
    頂!

    # re: 一個關(guān)于Java Socket的問題,大家看一下  回復(fù)  更多評論   

    2011-08-10 16:25 by careinlost
    我遇到了相同的問題,
    當(dāng)我在客戶端使用shutdownoutput時,服務(wù)端并未能完全獲取全部數(shù)據(jù)就拋出異常了,嘗試了client線程等待也不行。

    有什么辦法能夠使客戶端shutdownoutput前讓服務(wù)端接收完數(shù)據(jù),而不是在while(read)中等待?

    # re: 一個關(guān)于Java Socket的問題,大家看一下  回復(fù)  更多評論   

    2011-12-28 10:10 by Jawe
    樓主V5,解決了困擾我一天的問題

    # re: 一個關(guān)于Java Socket的問題,大家看一下  回復(fù)  更多評論   

    2012-09-26 09:25 by 飛飛俠
    看了半天,樓主還是沒有解決問題啊
    主站蜘蛛池模板: 国产AV无码专区亚洲A∨毛片| 亚洲精品在线免费观看| 免费在线看黄的网站| 亚洲综合亚洲国产尤物| 成人免费在线观看网站| 国产精品小视频免费无限app| 中文字幕亚洲综合精品一区| 日本成人免费在线| 国产在线观看免费av站| 久久亚洲国产成人影院| 中文字幕精品无码亚洲字| 精品香蕉在线观看免费| 男女拍拍拍免费视频网站| 亚洲国产综合在线| 久久久久亚洲?V成人无码| 国产啪精品视频网免费| 三级黄色免费观看| 亚洲第一成年免费网站| 亚洲国产成人私人影院| 亚洲AV无码成H人在线观看| 久久九九兔免费精品6| caoporn成人免费公开| 亚洲午夜成人精品无码色欲| 亚洲AV无码久久| jizzjizz亚洲| 成人免费视频88| 9277手机在线视频观看免费| 免费播放国产性色生活片| 亚洲18在线天美| 亚洲精品成人av在线| 亚洲另类激情专区小说图片| 久久久www成人免费毛片 | 日本高清免费观看| 国产精品亚洲综合一区在线观看 | 四虎影视在线永久免费看黄 | 妞干网免费视频在线观看| 久久精品私人影院免费看| 无遮挡免费一区二区三区| 亚洲一区二区观看播放| 亚洲人成日本在线观看| 亚洲伊人久久大香线蕉苏妲己|