매우 간단한 클라이언트 / 서버 연결을 시도하고 있습니다. 클라이언트로 Android 앱이 있으며
1) PC의 Java 프로그램에 메시지 전달 후
2) 안드로이드 클라이언트에 메시지를 반환합니다.
첫 번째 부분은 잘 작동합니다. 문제는 서버에서 클라이언트로 메시지를 반환하는 것입니다.
서버 코드 (Java) :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
private final static Integer IN_PORT = 4444;
private static ServerSocket serverSocket = null;
private static Socket sktIn;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
private static PrintWriter printWriter;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(IN_PORT); //Server socket
System.out.println("Server started. Listening to the port " + IN_PORT);
} catch (IOException e) {
System.out.println("Could not listen on port: " + IN_PORT);
}
while (true) {
try {
sktIn = serverSocket.accept(); //accept the client connection
inputStreamReader = new InputStreamReader(sktIn.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); //get the client message
message = bufferedReader.readLine();
printWriter = new PrintWriter(sktIn.getOutputStream(), true);
printWriter.write("Returned back \n"); //write the message to output stream
printWriter.flush();
printWriter.close();
inputStreamReader.close();
sktIn.close();
System.out.println(message);
} catch (IOException ex) {
System.out.println("Problem in message reading/sending.");
ex.printStackTrace();
}
}
}
}
클라이언트 주요 활동 (Android) :
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class SimpleClientActivity extends Activity {
private final Integer OUT_PORT = 4444;
private final String S_IP = "192.168.1.104";
private EditText textField;
private Button button;
private String message;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textField = (EditText) findViewById(R.id.editText1); //reference to the text field
button = (Button) findViewById(R.id.button1); //reference to the send button
//Button press event listener
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
message = textField.getText().toString(); //get the text message on the text field
textField.setText(""); //Reset the text field to blank
new ConnectClient(message, S_IP, OUT_PORT, getApplicationContext()).execute();
}
});
}
}
연결을위한 별도의 AsyncTask 클래스 :
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class ConnectClient extends AsyncTask<String, Void, String> {
private Socket socket;
private PrintWriter printWriter;
private String param;
private Context context;
private Integer PORT;
private String IP;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
public ConnectClient(String par, String ip, Integer prt, Context ctx){
super();
this.context = ctx;
this.param = par;
this.PORT = prt;
this.IP = ip;
}
@Override
public void onPreExecute() {
Toast.makeText(context, "start " + param, Toast.LENGTH_SHORT)
.show();
}
@Override
protected String doInBackground(String... params) {
try {
socket = new Socket(IP, PORT); //connect to server
printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.write(param); //write the message to output stream
printWriter.flush();
printWriter.close();
socket = new Socket(IP, PORT); // second connection to server
inputStreamReader = new InputStreamReader(socket.getInputStream());
message = "after isr";
bufferedReader = new BufferedReader(inputStreamReader); //get the client message
message = bufferedReader.readLine();
inputStreamReader.close();
socket.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return message;
}
@Override
protected void onPostExecute(String result) {
Toast.makeText(context, result, Toast.LENGTH_SHORT).show()
}
@Override
protected void onProgressUpdate(Void... values) {
Toast.makeText(context, "In progress", Toast.LENGTH_SHORT).show();
}
}
자바 프로그램은 정상적으로 실행되고 Android 앱은 문제없이 실행되지만 최종 결과는 원하는대로되지 않습니다.
두 번째를 제거하면 socket = new Socket(IP, PORT); // second connection to server
서버가 메시지를 정상적으로 수신합니다. 자바 콘솔에서 나는 앱에 넣은 모든 것을 인쇄하고 보냅니다. 그러나 두 번째 Toast는 비어 있습니다 (서버의 메시지가 전달되지 않음). 그리고 LogCat에서 SocketException (닫힘)이 발생합니다.
01-29 06:38:36.039: W/System.err(11547): java.net.SocketException: Socket is closed
01-29 06:38:36.059: W/System.err(11547): at java.net.PlainSocketImpl.checkNotClosed(PlainSocketImpl.java:134)
01-29 06:38:36.059: W/System.err(11547): at java.net.PlainSocketImpl.getInputStream(PlainSocketImpl.java:216)
01-29 06:38:36.059: W/System.err(11547): at java.net.Socket.getInputStream(Socket.java:343)
01-29 06:38:36.059: W/System.err(11547): at com.example.simpleclient.ConnectClient.doInBackground(ConnectClient.java:63)
01-29 06:38:36.059: W/System.err(11547): at com.example.simpleclient.ConnectClient.doInBackground(ConnectClient.java:1)
01-29 06:38:36.059: W/System.err(11547): at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-29 06:38:36.059: W/System.err(11547): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-29 06:38:36.059: W/System.err(11547): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-29 06:38:36.059: W/System.err(11547): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-29 06:38:36.059: W/System.err(11547): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-29 06:38:36.059: W/System.err(11547): at java.lang.Thread.run(Thread.java:841)
socket = new Socket(IP, PORT); // second connection to server
코드 줄을 남겨두면 오류 메시지는 없지만 메시지는 서버에 한 번만 전달됩니다. 2nd, 3rd, end 등은 통과하지 않습니다 (콘솔에 아무것도 표시되지 않음). 콘솔을 실행하고 앱을 종료하면 또 다른 null이 발생합니다.
어쨌든 두 번째 Toast (클라이언트 측)는 비어 있거나 (서버의 메시지가 전달되지 않음) 전혀 표시되지 않습니다 ( message = bufferedReader.readLine();
추가 실행 차단). 예를 들어, 줄을 주석 처리 message = bufferedReader.readLine();
하면 두 번째 Toast에서 "after isr"이 표시됩니다. 또는 socket = new Socket(IP, PORT); // second connection
두 번째 토스트가있는 경우 두 번째 토스트가 전혀 표시되지 않습니다.
나는 무엇을 놓치고있다. 서버에서 클라이언트로 메시지를 어떻게 보내나요?
클라이언트와 서버의 명령은 대칭이어야합니다.
클라이언트가 쓰는 경우 서버는 읽어야하며 그 반대의 경우도 마찬가지입니다.
클라이언트가 inputStream을 열면 서버는 outputStream을 열어야합니다.
이제 첫 번째 연결에서는 outputStream 만 열지 만 서버에는 둘 다 있습니다.
또한 서버에서 하나로 처리되는 두 개의 연결 (클라이언트)을 열면 서버에 읽기 작업이 있기 때문에 첫 번째 인쇄 작업은 제대로 작동하지만 서버에서 할 수없는 다른 연결을 생성하기 때문에 다른 연결은 작동하지 않습니다. 처리 이유 :
1) 서버가 다중 스레드가 아닙니다.
2) 서버는 첫 번째 연결에서 작동해야합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다