java 고수님... nio 에 관한 질문입니다.

maindb의 이미지

java 로 nio 를 이용하여 간단한 select 방식의 소켓서버를 만들었습니다.
정확히 말해서 만들었다기 보다는 java.sun.com 에 있는
소스입니다 ^^;

ByteBuffer sharedBuffer =
Selector selector =
ServerSocket serverSocket =

서버쪽 소켓 생성을 해서 accept 했는데...
socket = serverSocket.accept();
channel = socket.getChannel();

문제는.... 클라이언트에서 접속해서 어떤 문자열을 날렸습니다.
(클라이언트는 php 입니다. fsockopen() 으로 접속했죠)

접속 잘되고 아무런 문제없이 잘 작동합니다.
그런데 클라이언트에서 접속해서 날린 문자열을 되돌려서
클라이언트에게 쏴주는 것은 되는데 !!!!!!!!!!!!!!!!
그 클라이언트에서 날린 문자열을 변수에 담아서 실제로 출력을 해보려니
안됩니다... 이게 무슨 일인지....
해당 부분은 아래와 같습니다.

while ((bytes = socketChannel.read(sharedBuffer)) > 0)  
{ 
    System.out.println("Reading..."); 
    sharedBuffer.flip(); 

    while (sharedBuffer.hasRemaining())
    { 
        System.out.println("Exec...");
        System.out.println(sharedBuffer);
        socketChannel.write(sharedBuffer); 
    } 
    sharedBuffer.clear(); 
}

윗 부분 socketChannel.write(sharedBuffer);
와 같이 클라이언트에게 메세지 잘 되돌립니다.
그런데 System.out.println(sharedBuffer); 로 찍히지는 않네요.
정확히 이야기 해서 찍히지 않는것이 아니라

java.nio.DirectByteBuffer[pos=0 lim=12 cap=2048]

위 문자열이 찍힙니다. 위와 같은 이유는 대충 알겠는데...
어쨌든...
날라온 문자열을 변수에 담아서 따로 사용해야 하거든요.
이 부분에 있어서 조금만 조언을 부탁드립니다.

jinyeong의 이미지

이유를 대충 아시겠다면, 위의 println에서 저렇게 찍히는 이유도
nio 하고는 별로 관계없는 아실것 같군요.

System.out.println(new String(sharedBuffer.array()));

정도면 되지 않을까 싶습니다.

I thought what I'd do was,
I'd pretend I was one of those deaf-mutes.. or should I?

maindb의 이미지

조언 감사드립니다...

자바 공부를 시작한지 얼마안되서요 ㅡㅡ;;

String str = new String(sharedBuffer.array());

ByteBuffer를 사용했기 때문에
버퍼에 담긴 데이터를 얻어와서 String 으로 바꿔야 한다는
말씀이신것 같습니다.

그래서 아래와 같이 해봤는데 해당 부분에서
에러가 나고 프로그램이 죽어버리네요.

Exception in thread "main" java.lang.UnsupportedOperationException
at java.nio.ByteBuffer.array(ByteBuffer.java:939)

열심히 책 보고 찾아보고는 있는데...
워낙에 기본 내공이 부족해서... ㅜ.ㅜ
귀찮게 해드려서 죄송합니다.
조금만 더 힌트를 주시면 안될까요...

while ((bytes = socketChannel.read(sharedBuffer)) > 0)  
{ 
    System.out.println("Reading..."); 
    sharedBuffer.flip();

    String str = new String(sharedBuffer.array()); 

    while (sharedBuffer.hasRemaining()) 
    { 
        System.out.println("Exec..."); 
        // System.out.println(sharedBuffer); 
        socketChannel.write(sharedBuffer); 
    } 
    sharedBuffer.clear(); 
}
futari의 이미지

책보다는 레퍼런스를 보시는게 좋을 것 같습니다.

http://java.sun.com/j2se/1.5.0/docs/api/index.html

우선 ByteBuffer에서

Quote:
array
public final byte[] array()Returns the byte array that backs this buffer (optional operation).
Modifications to this buffer's content will cause the returned array's content to be modified, and vice versa.

Invoke the hasArray method before invoking this method in order to ensure that this buffer has an accessible backing array.

Returns:
The array that backs this buffer
Throws:
ReadOnlyBufferException - If this buffer is backed by an array but is read-only
UnsupportedOperationException - If this buffer is not backed by an accessible array

를 보시면 UnsupportedOperationException을 왜 던지는지 확인 하실 수 있구요.

그리고 꼭 ByteBuffer를 사용하셔야 하는 상황이 아니시라면 Stream계열을 사용하시는게 좋을 듯합니다.

그리고 궁금하신점은 sun의 java forum을 활용하시면 빠른 습득에 도움이 되실 것으로~~

그럼 자바 마스터를 위해 ㅋ

-------------------------
The universe is run by the complex interweaving of three elements: matter, energy, and enlightened self-interest.
- G'kar, Babylon 5

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.