Socket - Wysyłanie partiami textu

0

Witam,

Napisałam czat w javie - wszystko działa prawie idealnie - prawiem.

otóż po kliknieciu przycisku na applecie pobierany jest text (nick) - i jest on wysyłany do serwera.
Serwer jest w C++. Ale co się okazuje to czasami nick wysyłany jest jako jeden pakiet a czasami jako dwa pakiety.

Dla przykładu - jeśli nick to "agnieszka" wówczas serwer odbiera to tak

a
gnieszka

lub tak

agn
ieszka

a czasami normalnie jako:
agnieszka

No i tu jest problem bo chcę coś w stylu zrobić:

if (nick=="agnieszka") To_cosTam();

Natomiast kod klienta odpowiedzalny za wysyłanie to

    private void jButtonLogowanieMouseClicked(java.awt.event.MouseEvent evt) {                                              
        // TODO add your handling code here:
        String nick = jTextFieldNick.getText();
        String password = jTextFieldPassword.getText();      
        try
        {
            Socket s=null;
            s = new Socket();
            s.connect(new InetSocketAddress(IMCzat.myHost, 5000), 1000);
            jLabel1.setText("nawiozano polaczenie");
            //--------------------------------------------------------
            try
            {
                DataOutputStream out;
                OutputStream out_sock;
                out_sock = s.getOutputStream();
                out = new DataOutputStream ( out_sock );
                out.writeBytes(nick);
                jLabel1.setText(nick);
            }
            catch (IOException e)
            {
                System.err.println( e.getMessage());
                e.printStackTrace();
            }
          //----------------------------------------------------------
        }
        catch (java.net.UnknownHostException ex)
        {
            jLabel1.setText("Error_2" + ex);
        }
        catch (IOException ex)
        {
            jLabel1.setText("Error_1" + ex);
        }        
    }                                             

Natomiast fragment serwera;

        while(1)
        {
              ret = recv(sock, szBuf, DEFAULT_BUFFER, 0);
              if (ret == 0)  break; 
              else if (ret == SOCKET_ERROR)
              {
                   printf("blad funkcji recv(): %d\n", WSAGetLastError());
                   break; 
              } 

              szBuf[ret] = '\0';
              printf("RECV: '%s'\n", szBuf);
        }

I co to poradzicie

0

dwa rozwiazania:

  1. wysylasz najpierw z ilu liter sklada sie nick
  2. determinujesz znak koncza nicku (bedacy zakazanym zarazem znakiem)

i odpowiednio do wyboru swojego rozwiazania odczytuj te dane :)

0

W sumie racja to i dobry pomysł

Ale jak dokleić do Stringu jakiś znak.

np:

String nick = "agnieszka";
nick = nick + UNIKALNY_ZNAK_HEX;
0

Znak nowej linii ('\n')?

0

W zasadzie czy czasami znaku nowej lini to nie da sie wprowadzić podczas wklejania jakiegś textu z dokumentu? Jesli da się to raczej to nie było by dobre rozwiązanie.

W windows znak nowej lini to CR LF czyli 10 i 13 lub odwrotnie. A ja np chciała bym doklejać znak o kodzie np 9 - takiego raczej nie da się wprowadzić z klawiatury (nie mam tu na myśli cyfry tylko znak o kodzie 9) - bo jest to znak niedrukowany. Natomiast co do '\n' nie mam juz takiej pewności.

Pozdrawiam.

0

Znaku '\n' nie da się wprowadzić do JTextField, gdyż JTextField służy do edycji pojedynczej linii.

Z drugiej strony jednak, serwer nie powinien zakładać czegokolwiek o danych przesłanych przez sieć.
Atakujący może napisać własny program, który może wysłać zarówno \n, jak i dowolny inny znak (w tym ten o kodzie 9).

Jeszcze jeden szczegół: w Javie do porównywania napisów używa się metody equals, nie ==.

0

Jako że nick nie powinien zajmować więcej jak 255 znaków, w jednym bajcie można zapisać jego długość...
wysyłasz tak:

		String str = "Ala ma kota.";
		byte[] bytes = str.getBytes("UTF-8");
		out.write(bytes.length);
		out.write(bytes);

Na serwerze odczytuj bajty dopóki nie odczytasz podanej długości... nie napiszę Ci kodu w cpp, bo nie znam cpp

1 użytkowników online, w tym zalogowanych: 0, gości: 1