Sieci Komputerowe

Programowanie socketów. Różne języki *

Java

Przykład, server zamieniający komunikat na wielkie litery:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
//  ww w.  j a v a 2 s  . c  om
public class Main {
        public static void main(String[] args) throws Exception {
                ServerSocket serverSocket = new ServerSocket(12900, 100,
                InetAddress.getByName("localhost"));
                System.out.println("Server started  at:  " + serverSocket);

                while (true) {
                        System.out.println("Waiting for a  connection...");

                        final Socket activeSocket = serverSocket.accept();

                        System.out.println("Received a  connection from  " + activeSocket);
                        Runnable runnable = () -> handleClientRequest(activeSocket);
                        new Thread(runnable).start(); // start a new thread
                }
}

public static void handleClientRequest(Socket socket) {
        try{
                BufferedReader socketReader = null;
                BufferedWriter socketWriter = null;
                socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                socketWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

                String inMsg = null;
                while ((inMsg = socketReader.readLine()) != null) {
                        System.out.println("Received from  client: " + inMsg);

                        String outMsg = inMsg.toUpperCase();
                        socketWriter.write(outMsg);
                        socketWriter.write("\n");
                        socketWriter.flush();
                }
                socket.close();
                } catch(Exception e){
                e.printStackTrace();
        }

}
}

Klient, przykład:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
// ww w  .  jav  a2  s . c  o  m
public class Main {
                public static void main(String[] args) throws Exception {
                Socket socket = new Socket(12900);
                System.out.println("Started client  socket at " + socket.getLocalSocketAddress());
                BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                BufferedWriter socketWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));

                String promptMsg = "Please enter a  message  (Bye  to quit):";
                String outMsg = null;

                System.out.print(promptMsg);
                while ((outMsg = consoleReader.readLine()) != null) {
                        if (outMsg.equalsIgnoreCase("bye")) {
                                break;
                        }
                        // Add a new line to the message to the server,
                        // because the server reads one line at a time.
                        socketWriter.write(outMsg);
                        socketWriter.write("\n");
                        socketWriter.flush();

                        // Read and display the message from the server
                        String inMsg = socketReader.readLine();
                        System.out.println("Server: " + inMsg);
                        System.out.println(); // Print a blank line
                        System.out.print(promptMsg);
                }
                socket.close();
        }
}

Więcej informacji

Problemy

W Javie mamy dwa sposoby przetwarzania danych InputStream (bajowo kodowany) oraz Reader (znakowo). Stream is for reading bytes, Reader is for reading characters. One character may take one byte or more, depending on character set. Powinniśmy raczej korzystać w kodzie z jednego sposobu przetwarzania danych.

Serwer:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
//  ww w.  j a v a 2 s  . c  om

public class Main {

        public static void main(String[] args) throws Exception {
                String sentence;
                ServerSocket welcomeSocket = new ServerSocket(6789);
                Socket connSocket = welcomeSocket.accept();
                BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connSocket.getInputStream()));

                while (true) {
                        sentence = inFromClient.readLine();
                        System.out.println(sentence);
                        DataOutputStream outToClient = new DataOutputStream(connSocket.getOutputStream());
                        outToClient.writeBytes(sentence.toUpperCase());
                        outToClient.flush();
                }
        }
}

Klient:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
// ww w  .  jav  a2  s . c  o  m

public class Client {

        public static void main(String[] args) throws Exception {
                String sentence = "hello";
                Socket clientSocket = new Socket("localhost", 6789);
                DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
                outToServer.writeBytes(sentence + '\n');
                BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                System.out.println(inFromServer.readLine());
                clientSocket.close();
        }
}

Sprawdź jak reaguje powyższy client, co jest nie tak? dlaczego serwer nie odsyła klientowi komunikatu??

Zadanie (10 pkt)

Zadaniem Państwa jest napisanie programu grającego w grę kółko i krzyżyk na planszy 5x5, gdzie wygrywającymi układami są proste poziome, pionowe oraz przekątne. Państwa program gra z komputerem a w przypadku remisu na koniec gry, jest on traktowany jak Państwa wygrana. Program rozgrywa po 50 gier i jego zadaniem jest wygranie co najmniej 40 z nich.

Komunikacja z serwerem: Na powitanie Serwer przesyła komunikat:

WELCOME, STATE YOUR NAME

I oczekuje od klienta na wysłanie Swojego loginu w postaci

LOGIN imie_nazwisko

Każdy poprawnie odebrany i sparsowany komunikat przez serwer potwierdzany jest komunikatem OK, każdy błędny komunikat oznaczany jest przez serwer poprzez przesłanie do klienta ERROR.

Następnie serwer czeka na spis ruchów użytkownika w postaci:

MOVE nr między 0 a 25

W odpowiedzi wysyłany jest albo ruch przeciwnika postaci:

OPPONENT nr między 0 a 25

Albo komunikat o wygranej

WIN

albo pregranej

LOST

Po wygranej lub przegranej przesyłany jest także komunikat o rozpoczęciu nowej gry

NEW GAME

I serwer oczekuje na ruch użytkownika w nowej grze.

Po zakończeniu 50 gier użytkownik powiadamiany jest o wykonaniu zadania - komunikat "SUCCESS" lub porażce - komunikat "FAILED" i serwer kończy komunikację z użytkownikiem (zamyka socket). Każdy komunikat kończy się znakiem końca linii '\n'.

Jako rozwiązanie proszę także przesłać kod państwa programu.

Kod klienta proszę przesłać przez stronę:

*

Wykorzystano materiały z:

http://www.java2s.com/Tutorials/Java/Java_Network/0020__Java_Network_TCP_Client_Socket.htm

http://www.java2s.com/Tutorials/Java/Java_Network/0010__Java_Network_TCP_Server.htm