Я собираюсь объяснить TCP:
Основная концепция заключается в том, что вы должны запустить «Сервер» на машине. Этот сервер принимает клиентов, ожидающих соединения. Каждое соединение проходит через порт (вы знаете, я надеюсь ...).
Всегда используйте порты выше 1024, потому что порты ниже 1025 большую часть времени зарезервированы для стандартных протоколов (таких как HTTP (80), FTP (21), Telnet, ...)
Однако создание сервера в Java выполняется следующим образом:
ServerSocket server = new ServerSocket(8888); // 8888 is the port the server will listen on.
«Сокет» - это слово, которое вы, вероятно, ищете, если хотите провести исследование.
И чтобы подключить клиента к серверу, вы должны написать это:
Socket connectionToTheServer = new Socket("localhost", 8888); // First param: server-address, Second: the port
Но сейчас еще нет связи. Сервер должен принять ожидающего клиента (как я заметил здесь выше):
Socket connectionToTheClient = server.accept();
Готово! Ваше соединение установлено! Общение - это как File-IO. Единственное, что вы должны иметь в виду, это то, что вы должны решить, когда вы хотите очистить буфер и действительно отправлять данные через сокет.
Использование PrintStream для написания текста очень удобно:
OutputStream out = yourSocketHere.getOutputStream();
PrintStream ps = new PrintStream(out, true); // Second param: auto-flush on write = true
ps.println("Hello, Other side of the connection!");
// Now, you don't have to flush it, because of the auto-flush flag we turned on.
Хорошим (лучшим *) вариантом является BufferedReader для чтения текста:
InputStream in = yourSocketHere.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = br.readLine();
System.out.println(line); // Prints "Hello, Other side of the connection!", in this example (if this would be the other side of the connection.
Надеюсь, вы можете начать с сети с этой информацией!
PS: Конечно, весь сетевой код должен быть перехвачен для IOExceptions.
РЕДАКТИРОВАТЬ: Я забыл написать, почему это не всегда лучший вариант. BufferedReader использует буфер и читает как можно больше в буфер. Но иногда вы не хотите, чтобы BufferedReader крал байты после новой строки и помещал их в свой собственный буфер.
Краткий пример:
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// The other side says hello:
String text = br.readLine();
// For whatever reason, you want to read one single byte from the stream,
// That single byte, just after the newline:
byte b = (byte) in.read();
Но у BufferedReader уже есть этот байт, который вы хотите прочитать, в своем буфере. Таким образом, вызов in.read()
вернет байт, следующий за последним байтом в буфере считывателя.
Итак, в этой ситуации лучшее решение - использовать DataInputStream
и управлять им по-своему, чтобы узнать, какой длины будет строка, и прочитать только это количество байтов и преобразовать их в строку. Или: Вы используете
DataInputStream.<del>readLine()</del>
Этот метод не использует буфер и читает побайтно и проверяет наличие новой строки. Так что этот метод не крадет байты из базового InputStream.
РЕДАКТИРОВАТЬ: вы можете разработать свой собственный протокол, в котором вы можете запросить вызов метода с помощью Java Reflexion. Например:
String className = ...;
String methodName = ...;
Class[] methodParamTypes = ...;
Object[] methodParams = ...;
Class cl = Class.forName(className);
Method me = cl.getDelcaredMethod(methodName, methodParamTypes);
Object returnValue = me.invoke(this, methodParams);
Получив свой объект, вы можете отправить его на другую сторону соединения с сериализацией: ObjectOuputStreams
и ObjectInputStreams
. С помощью этих двух классов вы можете писать и читать объекты через поток.
Object obj = ...; // Your object you want to write through the stream. (Needs to implement java.io.Serializable)
ObjectOutputStream oos = new ObjectOuptputStream(socket.getOutputStream());
oos.writeObject(oos);
oos.reset(); // (***)
// Don't close it! Otherwise the connection will be closed as well.
А на другой стороне соединения:
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object object = ois.readObject(); // Read the object
// Don't close it!
// Then cast it to whatever you want.
(***)
: Проверьте мой вопрос для получения дополнительной информации о reset()
и когда его использовать.