I wrote the below socket communication code in Java. When I checked the protocol with WireShark, it said TCP protocol, not HTTP protocol. Didn't I follow the HTTP header format? I want to pop up with HTTP protocol when captured with WireShark. How do I modify the code?
Here is MyServer.java
:
import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStream;
import java.io.DataInputStream;
import java.io.OutputStream;
import java.io.DataOutputStream;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class MyServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
DataInputStream dataInputStream = null;
OutputStream outputStream = null;
DataOutputStream dataOutputStream = null;
String blank = "";
try {
serverSocket = new ServerSocket(9000);
System.out.println("클라이언트로부터 데이터 전송받을 준비 완료");
socket = serverSocket.accept();
System.out.println("클라이언트 연결 완료");
System.out.println("socket: " socket);
inputStream = socket.getInputStream();
dataInputStream = new DataInputStream(inputStream);
outputStream = socket.getOutputStream();
dataOutputStream = new DataOutputStream(outputStream);
while (true) {
String clientMessage = dataInputStream.readUTF();
String[] clientMessages = clientMessage.split("\r\n");
String slot1 = clientMessages[0]; // 예시) "GET / HTTP/1.1"
String[] slot2 = slot1.split(" ");
String request_method = slot2[0]; // 예시) GET
String request_version = slot2[2]; // 예시) HTTP/1.1
String server_name = "Socket Server";
String strDate = "";
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
strDate = sdf.format(date);
String response_data = "";
if (request_method.equals("GET") && request_version.equals("HTTP/1.1")){
System.out.printf("%s %s 200\n", request_method, request_version);
response_data = String.format("%s 200 OK\nServer: %s\nDate: %s\n", request_version, server_name, strDate);
}
else if (request_method.equals("POST") && request_version.equals("HTTP/1.1")){
System.out.printf("%s %s 201", request_method, request_version);
response_data = String.format("%s 201 OK\nServer: %s\nDate: %s\n", request_version, server_name, strDate);
}
else if (request_method.equals("HEAD") && request_version.equals("HTTP/1.1")){
System.out.printf("%s %s 203", request_method, request_version);
response_data = String.format("%s 203 OK\nServer: %s\nDate: %s\n", request_version, server_name, strDate);
}
else if (request_method.equals("PUT") && request_version.equals("HTTP/1.1")){
System.out.printf("%s %s 202", request_method, request_version);
response_data = String.format("%s 202 OK\nServer: %s\nDate: %s\n", request_version, server_name, strDate);
}
else if (request_method.equals("DELETE") && request_version.equals("HTTP/1.1")){
System.out.printf("%s %s 204", request_method, request_version);
response_data = String.format("%s 204 OK\nServer: %s\nDate: %s\n", request_version, server_name, strDate);
}
else {
System.out.printf("%s %s 405", request_method, request_version);
response_data = String.format("%s 405 OK\nServer: %s\nDate: %s\n", request_version, server_name, strDate);
}
dataOutputStream.writeUTF(response_data);
dataOutputStream.flush();
if (clientMessage.equals("STOP")) break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (dataOutputStream != null) dataOutputStream.close();
if (outputStream != null) outputStream.close();
if (dataInputStream != null) dataInputStream.close();
if (inputStream != null) inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Here is MyClient.java
:
public class MyClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
DataOutputStream dataOutputStream = null;
InputStream inputStream = null;
DataInputStream dataInputStream = null;
String inputMessage = "";
String outputMessage = "";
Scanner scanner = null;
try{
socket = new Socket("localhost", 9000);
System.out.println("서버 연결 완료");
outputStream = socket.getOutputStream();
dataOutputStream = new DataOutputStream(outputStream);
inputStream = socket.getInputStream();
dataInputStream = new DataInputStream(inputStream);
scanner = new Scanner(System.in);
while(true){
System.out.print("메세지를 입력해주세요:");
inputMessage = scanner.next();
if (inputMessage.equals("GET")) {
outputMessage = "GET / HTTP/1.1\r\nHost: 127.0.0.1:9000\r\nUser-Agent: Mozilla/5.0\r\nAccept: */*\r\n\r\n";
} else if (inputMessage.equals("POST")) {
outputMessage = "POST / HTTP/1.1\r\nHost: 127.0.0.1:9000\r\nUser-Agent: insomnia/2022.2.1\r\nAccept: */*\r\nContent-Length: 0\r\n\r\n";
} else if (inputMessage.equals("HEAD")) {
outputMessage = "HEAD / HTTP/1.1\r\nHost: 127.0.0.1:9000\r\nUser-Agent: insomnia/2022.2.1\r\nAccept: */*\r\n\r\n";
} else if (inputMessage.equals("PUT")) {
outputMessage = "PUT / HTTP/1.1\r\nHost: 127.0.0.1:9000\r\nUser-Agent: insomnia/2022.2.1\r\nAccept: */*\r\nContent-Length: 0\r\n\r\n";
} else if (inputMessage.equals("DELETE")) {
outputMessage = "DELETE / HTTP/1.1\r\nHost: 127.0.0.1:9000\r\nUser-Agent: insomnia/2022.2.1\r\nAccept: */*\r\n\r\n";
} else {
outputMessage = "NotAllowed / HTTP/1.1\r\nHost: 127.0.0.1:9000\r\nUser-Agent: insomnia/2022.2.1\r\nAccept: */*\r\n\r\n";
}
dataOutputStream.writeUTF(outputMessage);
dataOutputStream.flush();
String receivedMessage = dataInputStream.readUTF();
System.out.println(receivedMessage);
if (inputMessage.equals("STOP")) break;
}
} catch (Exception e){
e.printStackTrace();
} finally {
try{
if (dataOutputStream != null) dataOutputStream.close();
if (outputStream != null) outputStream.close();
if (dataInputStream != null) dataInputStream.close();
if (inputStream != null) inputStream.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
}
CodePudding user response:
The Data Input/Output streams send and receive serialized Java objects. This was a solution to the "endian" problem that existed back in 1994 (but no longer exists) You want raw bytes, so just stick to plain Input and Output streams.
Also, just FYI (not in your question but I've added anyway): Stream buffers improve performance only when you are doing inefficient reading and writing. If you are just gobbling bytes as quickly as possible (using a byte[] with InputStream's read method) you don't need a buffer. If, however, you want to read line by line (ie inefficient reading) a buffer will help.
Likewise, a BufferedOutputStream can help if you are doing multiple small writes... BufferedOutputStream will store the data until there is sufficient data to send, rather than sending out multiple small data packets