java로 프로세스 스트림 리다이렉션이 한박자 밀립니다 ...

jaykee33의 이미지

자바로 서버를 만들려고하는데,
1차 목표로 일단 서버의 프로그램을 실행해서 스트림을 받아와서 사용해야되는데요,
입력이 없는 프로그램은 잘되는데, 입력이 존재하는 프로그램은 프로세스가 시작되고 입력 전 출력이 안되더라구요??
아무래도 입력,출력이 정해져있지 않아서 스레드로 돌리려는데 당최 이해가 안되서요.

package test1;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
 
 
public class test3 {
	public static void main(String[] args){
		Process ps=null;
		Runtime rt=null;
		try{
			rt = Runtime.getRuntime();
			ps=rt.exec("C:\\temp\\test.exe");
			Thread thread1 = new ReceiverThread(ps);
			Thread thread2 = new SenderThread(ps);
			thread1.start();
			thread2.start();
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
}
class SenderThread extends Thread{
	Process ps;
	SenderThread(Process ps){
		this.ps = ps;
	}
	public void run(){
		try{
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			PrintWriter writer = new PrintWriter(ps.getOutputStream());
			String msg=null;
			while(true){
				msg=reader.readLine();
				if(msg==null)
					continue;
				writer.println(msg);
				writer.flush();
			}
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
}
class ReceiverThread extends Thread{
	Process ps;
	ReceiverThread(Process ps){
		this.ps = ps;
	}
	public void run(){
		try{
			BufferedReader reader = new BufferedReader(new InputStreamReader(ps.getInputStream()));
			PrintWriter writer = new PrintWriter(System.out);
			String msg=null;
			while(true){
				msg=reader.readLine();
				if(msg==null)
					continue;
				writer.print(msg);
				writer.flush();
			}
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
	}
}

너무 답답해서 테스트코드 전문 붙입니다.
참고로 test.exe 의 코드는 간단하게 입출력 테스트입니다
#include <stdio.h> 
void main(void)
{
	int a;
	printf("Hello J : ");
	scanf("%d",&a);
	printf("print : %d",a);
}

실행은 되는데 출력이
5
Hello J : print : 5

이렇게 입력을 먼저 받아서 한방에 출력해버립니다.
제가 원하는건
Hello J : 5
print : 5

이런 결과인데 말이죠...
한마디로 출력>입력>출력 이런 순서의 프로그램인데
(사전출력X) 입력>출력 이렇게 되버린다는거죠
혹시 뭐가 문제인지 알려주실수 있으신 분 ㅜㅜ?
ProcessBuilder 이용해서 해도 같은증상입니다 ㅜ
참고로 개발환경 이클립스입니다

--- 자꾸 사람들이 C코드를 조언해줘서 테스트코드 파이썬으로 바꾸겠습니다. 테스트코드문제가 아닙니다.

def main():
    print "start py!\n";
    aaa=input();
    print "hello world",aaa;
 
if __name__ == '__main__':
    main()

이 프로그램의 결과도
3
start py!hello world 3

이렇게 입력을 먼저 받아버립니다.
tyhan의 이미지

아래와 같이 하면 어떻게 되나요?

#include <stdio.h> 
void main(void)
{
	int a;
	printf("Hello J : ");
	scanf("%d",&a);
	printf("\n");
	printf("print : %d\n",a);
}
tyhan의 이미지

그리고 원하신 결과

Hello J : 5
print : 5

에서 Hello J 뒤의 5는 stdout이 아닌 것도 알아야할 부분입니다.
jaykee33의 이미지

똑같은데요.. 외부프로그램코드가 문제가아니고 자바코드가 문제인거같아요

3
Hello J :
print : 3

tyhan의 이미지

줄바꾸기를 기다리는 문제인줄 알았는데 아니네요.
자바쪽에서 stdout을 확인후 5를 입력하게 수정하여야 할것 같은데.
java는 제가 모르네요. 혼란을 드려 송구스럽네요.

bushi의 이미지

다른 질문글에서 BufferedReader.readLine() 의 오남용에 대한 지적을 이미 받으셨는데, 답변 읽지 않으시네요.
이전 질문 글에서는 (버퍼가 꽉 차거나) 개행문자를 만남과 동시에 처리가 끝난다는 것을 몰라서 헤메시는 것이고,
이번엔 (버퍼가 꽉 차거나) 개행문자를 만나기 전에는 처리가 끝나지 않는다는 것을 모르기 때문에 헤메시는 겁니다.
https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()

C/Python 의 standard output 도 디폴트는 line buffered 입니다.
https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#BufferedReader(java.io.Reader,%20int)
이용해서 자바쪽의 버퍼를 1로 줄여봐야 나아지지 않는다고 말씀드리는 겁니다.
C/Python 에서도 standard output 에 대해 fflush() 하던가 버퍼 크기를 줄이던가 아예 non-buffered 로 바꾸던가하세요.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.