JavaRush /Блоги Java /Random-TG /Синфҳои Socket ва ServerSocket, ё "Салом, сервер? Маро ме...
Sergey Simonov
Сатҳи
Санкт-Петербург

Синфҳои Socket ва ServerSocket, ё "Салом, сервер? Маро мешунавед?"

Дар гурӯҳ нашр шудааст
Муқаддима: «Дар рӯйи миз компютер буд, дар паси он рамзгузор буд...» Синфҳои Socket ва ServerSocket, ё "Салом, server?  Маро мешунавед?"  - 1 Боре яке аз ҳамсинфонам натиҷаи омӯзиши Java-ро дар шакли скриншоти барномаи нав нашр карда буд. Ин барнома як сӯҳбати бисёркорбар буд. Дар он вақт ман танҳо ба сафари худ дар азхудкунии барномасозӣ бо ин забон шурӯъ кардам, аммо ман бешубҳа ба худ қайд кардам, ки "Ман инро мехоҳам!" Вақт гузашт ва бо анҷом додани кор дар лоиҳаи навбатӣ ҳамчун як қисми амиқтар кардани дониши барномасозӣ ман он ҳодисаро ба ёд овардам ва қарор додам, ки вақт расидааст. Ба гунае ки ман аллакай ба кофтани ин мавзӯъ танҳо аз рӯи кунҷковӣ шурӯъ кардам, аммо дар китоби асосии Java (он дастури пурраи Шилдт буд) барои бастаи java.net ҳамагӣ 20 саҳифа пешбинӣ шуда буд. Ин фахмост — китоб аллакай хеле калон аст. Ҷадвалҳои усулҳо ва конструкторҳои синфҳои асосӣ мавҷуданд, аммо ин ҳама аст. Қадами навбатӣ, албатта, Google-и абарқудрат аст: шумораи зиёди мақолаҳои гуногун, ки дар он як чиз пешниҳод карда мешавад - ду ё се калима дар бораи розеткаҳо ва як мисоли тайёр. Муносибати классикӣ (ҳадди ақал дар услуби таҳсor ман) ин аст, ки аввал фаҳмидани асбобҳои кор ба ман чӣ лозим аст, онҳо чӣ гунаанд, барои чӣ онҳо лозиманд ва танҳо пас аз он, агар ҳалли мушкилот аён набошад, листингхои тайёр, бур-дани гайкаю болтхо. Аммо ман фаҳмидам, ки чӣ аст ва дар ниҳоят чати бисёркорбар навиштам. Ба таври берунӣ, ин чунин буд: Синфҳои Socket ва ServerSocket, ё "Салом, server?  Маро мешунавед?"  - 2Дар ин ҷо ман кӯшиш мекунам, ки бо истифода аз намунаи тарҳрезии чат ба шумо дар бораи асосҳои замимаҳои муштарӣ-server дар асоси розеткаҳои Java маълумот диҳам. Дар курси Javarash шумо сӯҳбат мекунед. Он дар сатҳи комилан дигар, зебо, калон, бисёрфунксионалӣ хоҳад буд. Аммо пеш аз ҳама, шумо бояд ҳамеша таҳкурсӣ гузоред, бинобар ин, дар ин ҷо мо бояд фаҳмем, ки ин қисмат чӣ гуна аст. (Агар шумо ягон камбудӣ ё хатогие пайдо кунед, дар PM ё дар шарҳи зери мақола нависед). Биёед оғоз кунем. Сарвари якум: "Хонае, ки ..." Барои фаҳмонидани он ки чӣ гуна пайвасти шабакавӣ байни server ва як муштарӣ рух медиҳад, биёед мисоли ҳозираи классикии бинои истиқоматиро гирем. Фарз мекунем, ки муштарӣ бояд бо кадом роҳе бо serverи мушаххас робита барқарор кунад. Ҷустуҷӯ бояд дар бораи an objectи ҷустуҷӯ чиро донад? Ҳа, address. Сервер як воҳиди ҷодугарӣ дар абр нест ва аз ин рӯ он бояд дар як мошини мушаххас ҷойгир бошад. Дар мисоли хонае, ки дар он бояд вохӯрии ду ҷониб мувофиқашуда баргузор шавад. Ва барои дар бинои истицоматй пайдо кардани хамдигар як addressи бино кифоя нест, шумо бояд раками квартираеро, ки дар он мачлис барпо мегардад, нишон дихед. Ба ин монанд, дар як компютер якбора якчанд server мавҷуд буда метавонад ва барои он ки муштарӣ бо serverи мушаххас тамос гирад, вай инчунин бояд рақами портеро, ки тавассути он пайвастшавӣ сурат мегирад, муайян кунад. Ҳамин тавр, суроға ва рақами порт. Суроға маънои муайянкунандаи мошинро дар фазои интернет дорад. Он метавонад номи домейн бошад, масалан, "javarush.ru" ё IP муқаррарӣ. Порт- рақами беназире, ки розеткаи мушаххас бо он алоқаманд аст (ин истилоҳ баъдтар баррасӣ хоҳад шуд), ба ибораи дигар, он дар як хидмати муайян ҷойгир аст, то он метавонад барои тамос бо он истифода шавад. Ҳамин тавр, барои он ки ҳадди аққал ду an object дар ҳудуди як (server) вохӯранд, соҳиби майдон (server) бояд як манзor (порти) мушаххаси он (мошин) ишғол кунад ва дуюмӣ бояд ҷои вохӯриро донист. суроғаи хона (домен ё ip ) ва рақами хона (порт). Сарвари дуюм: Вохӯрӣ бо розетка Дар байни мафҳумҳо ва истилоҳҳои марбут ба кор дар шабака яке аз муҳимтаринаш Socket аст. Он нуқтаеро ифода мекунад, ки тавассути он пайвастшавӣ ба амал меояд. Оддӣ карда гӯем, розетка ду барномаро дар шабака мепайвандад. Синф Socketидеяи розеткаро амалӣ мекунад. Мизоҷ ва server тавассути каналҳои вуруд/баромади худ муошират хоҳанд кард: Синфҳои Socket ва ServerSocket, ё "Салом, server?  Маро мешунавед?"  - 3 Ин синф дар тарафи муштарӣ эълон карда мешавад ва server онро дубора эҷод мекунад ва сигнали пайвастшавӣ мегирад. Ин аст, ки муоширати онлайн кор мекунад. Барои оғоз, инҳо конструкторҳои имконпазири синф мебошанд Socket:
Socket(String Name_хоста, int порт) throws UnknownHostException, IOException
Socket(InetAddress IP-address, int порт) throws UnknownHostException
"Номи_хост" - гиреҳи мушаххаси шабака, суроғаи IP-ро дар назар дорад. Агар синфи розетка онро ба суроғаи воқеӣ ва мавҷуда табдил дода натавонист, он гоҳ истисно партофта мешавад UnknownHostException. Порт бандар аст. Агар 0 ҳамчун рақами порт муайян карда шуда бошад, худи система як порти ройгонро ҷудо мекунад. Истисно инчунин метавонад рух диҳад, агар пайвастшавӣ гум шавад IOException. Бояд қайд кард, ки навъи суроға дар конструктори дуюм аст InetAddress. Масалан, вақте ки шумо бояд номи доменро ҳамчун суроға муайян кунед, он ба наҷот меояд. Инчунин, вақте ки домен маънои якчанд суроғаҳои IP-ро дорад, InetAddressшумо метавонед онҳоро барои гирифтани массиви онҳо истифода баред. Бо вуҷуди ин, он бо IP низ кор мекунад. Шумо инчунин метавонед номи мизбон, массиви byteро, ки суроғаи IP-ро ташкил медиҳад, ва ғайра гиред. Мо ба он каме бештар дахл хоҳем кард, аммо шумо бояд барои тафсилоти пурра ба ҳуҷҷатҳои расмӣ муроҷиат кунед. Вақте ки an objectи навъи оғоз карда мешавад Socket, муштарӣ, ки ба он тааллуқ дорад, дар шабака эълон мекунад, ки мехоҳад ба server бо суроғаи мушаххас ва рақами порт пайваст шавад. Дар зер усулҳои бештар истифодашавандаи синф оварда шудаанд Socket: InetAddress getInetAddress()– an objectеро, ки дорои маълумот дар бораи розетка мебошад, бармегардонад. Агар розетка пайваст набошад - null int getPort()- портеро бар мегардонад, ки дар он пайвастшавӣ ба server рух медиҳад int getLocalPort()- портеро, ки розетка ба он пайваст аст, бармегардонад. Гап дар он аст, ки муштарӣ ва server метавонанд дар як порт "муошират" кунанд, аммо портҳое, ки онҳо ба онҳо пайваст мешаванд, метавонанд комилан гуногун бошанд boolean isConnected()- ҳақиқӣ бармегардад, агар пайвастшавӣ барқарор карда шавад void connect(SocketAddress address)- пайвасти навро нишон медиҳад boolean isClosed()- ҳақиқӣ бармегардад, агар розетка баста бошад boolean isBound()- ҳақиқиро бармегардонад, агар розетка воқеан ба суроға пайваст бошад, синф Socketинтерфейсро амалӣ мекунад AutoCloseable, аз ин рӯ он метавонад дар try-with-resources. Аммо, шумо инчунин метавонед розеткаро бо роҳи классикӣ бо истифода аз close() пӯшед. Сарвари се: ва ин ServerSocket аст Биё бигӯем, ки мо дар шакли синф Socketдархости пайвастшавӣ дар тарафи муштарӣ эълон кардем. Чӣ тавр server хоҳиши моро тахмин мекунад? Барои ин, server дорои синф ба монанди ServerSocket, ва усули accept() дар он. Конструкторҳои он дар зер оварда шудаанд:
ServerSocket() throws IOException
ServerSocket(int порт) throws IOException
ServerSocket(int порт, int максимум_подключений) throws IOException
ServerSocket(int порт, int максимум_подключений, InetAddress локальный_address) throws IOException
Ҳангоми декларатсия ServerSocket ба шумо суроғаи пайвастшавӣ лозим нест, зеро алоқа дар мошини server сурат мегирад. Танҳо бо мизбони бисёрканал шумо бояд муайян кунед, ки васлаки server ба кадом IP пайваст аст. Head Three.One: Сервере, ки мегӯяд Не, Азбаски таъмин кардани барнома бо захираҳои бештар аз он ки лозим аст, ҳам гарон ва ҳам беасос аст, бинобар ин дар созанда аз ServerSocketшумо хоҳиш карда мешавад, ки ҳадди аксар пайвастҳои қабулкардаи serverро ҳангоми кор эълон кунед. Агар нишон дода нашуда бошад, пас аз рӯи нобаёнӣ ин рақам ба 50 баробар ҳисобида мешавад. Бале, дар назария мо метавонем тахмин кунем, ки ServerSocketин як розетка аст, танҳо барои server. Аммо он наќши тамоман дигар аз синф мебозад Socket. Он танҳо дар марҳилаи эҷоди пайвастшавӣ лозим аст. Пас аз сохтани an objectи навъи, ServerSocketшумо бояд фаҳмед, ки касе мехоҳад ба server пайваст шавад. Усули accept() дар ин ҷо пайваст аст. Ҳадаф интизор мешавад, ки касе мехоҳад ба он пайваст шавад ва вақте ки ин рӯй медиҳад, an objectи навъи Socket, яъне васлаки муштарии аз нав сохташударо бармегардонад. Ва акнун, ки васлаки муштарӣ дар тарафи server сохта шудааст, алоқаи дуҷониба метавонад оғоз шавад. Эҷоди an objectи навъи Socketдар тарафи муштарӣ ва аз нав сохтани он бо истифода аз ServerSocketтарафи server ҳадди ақали барои пайвастшавӣ зарур аст. Сарвари чаҳор: Мактуб ба Бобои Барфӣ Вопрос: Чӣ тавр муштарӣ ва server муошират мекунанд? Ответ:Тавассути ҷараёнҳои I/O. Мо аллакай чӣ дорем? Розетка бо суроғаи server ва рақами бандари муштарӣ ва ҳамин чиз ба шарофати accept(), дар тарафи server. Ҳамин тавр, тахмин кардан дуруст аст, ки онҳо тавассути розетка муошират мекунанд. Барои ин ду усул вуҷуд дорад, ки дастрасӣ ба ҷараёнҳо InputStreamва OutputStreaman objectҳои навъи Socket. Инҳоянд:
InputStream getInputStream()
OutputStream getOutputStream()
Азбаски хондан ва навиштани byteҳои луч чандон самаранок нест, ҷараёнҳоро метавон дар синфҳои адаптер печонд, буферӣ ё не. Барои намуна:
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
Барои он ки муошират дуҷониба бошад, чунин амалиётҳо бояд аз ҳарду ҷониб анҷом дода шаванд. Акнун шумо метавонед чизеро бо истифода аз дохил фиристед ва чизеро бо истифода аз берун қабул кунед ва баръакс. Дар асл, ин амалан ягона вазифаи синф аст Socket. Ва ҳа, дар бораи усули flush () фаромӯш накунед BufferedWriter- он мундариҷаи буферро тоза мекунад. Агар ин кор карда нашавад, маълумот интиқол дода намешавад ва аз ин рӯ, қабул карда намешавад. Риштаи қабулкунанда низ мунтазири нишондиҳандаи охири сатр – “\n” аст, вагарна паём қабул карда намешавад, зеро дар асл паём пурра нест ва пурра нест. Агар ин барои шумо номувофиқ бошад, хавотир нашавед, шумо ҳамеша метавонед class ро истифода баред PrintWriter, ки бояд ба охир расад, ҳамчун далели дуюм true нишон диҳед ва пас аз буфер ба таври худкор пайдо мешавад:
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Инчунин, нишон додани охири сатр лозим нест; ин синф онро барои шумо мекунад. Аммо оё сатри I/O маҳдудияти коре, ки розетка карда метавонад? Не, оё шумо мехоҳед an objectҳоро тавассути ҷараёнҳои розетка фиристед? Аз барои Худо. Онҳоро сериал кунед ва шумо хуб меравед:
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Сарвари Панҷ: Муоширати воқеӣ тавассути Интернет Азбаски барои пайваст шудан тавассути шабакаи воқеӣ бо суроғаи IP воқеӣ шумо бояд serverи мукаммал дошта бошед ва аз ин рӯ:
  1. Чати ояндаи мо, ҳамчун коммуналӣ, чунин қобorятҳоро надорад. Он танҳо метавонад пайвастшавӣ барқарор кунад ва паём қабул кунад/фиристад. Яъне он имкониятҳои воқеии server надорад.
  2. Сервери мо, ки танҳо маълумотҳои розетка ва ҷараёнҳои I/O дорад, наметавонад ҳамчун serverи воқеии WEB ё FTP кор кунад, пас танҳо бо ин мо тавассути Интернет пайваст шуда наметавонем.
Ғайр аз он, мо нав ба таҳияи барнома шурӯъ карда истодаем, ки ин маънои онро дорад, ки он барои фавран кор кардан бо шабакаи воқеӣ кофӣ устувор нест, аз ин рӯ мо хости маҳаллиро ҳамчун суроғаи пайваст истифода хоҳем кард. Яъне, дар назария, муштарӣ ва server то ҳол ба ҳеҷ ваҷҳ ба ҷуз тавассути розетка пайваст намешаванд, аммо барои ислоҳи барнома онҳо дар як мошин, бидуни тамоси воқеӣ тавассути шабака хоҳанд буд. Барои дар конструктор нишон додани Socketсуроғаи маҳаллӣ, ду роҳ вуҷуд дорад:
  1. Ҳамчун далели суроға "localhost" -ро нависед, ки маънои ноустувори маҳаллиро дорад. "127.0.0.1" низ барои ин мувофиқ аст - ин танҳо як шакли рақамии ноустувор аст.
  2. Истифодаи InetAddress:
    1. InetAddress.getByName(null)- нул ишора ба localhost
    2. InetAddress.getByName("localhost")
    3. InetAddress.getByName("127.0.0.1")
Барои содда, мо "localhost" -и навъи String -ро истифода хоҳем бурд. Аммо ҳамаи имконоти дигар низ қобor коранд. Сарвари шаш: Вақти сӯҳбат фаро расид Пас, мо аллакай ҳама чизеро дорем, ки барои амалӣ кардани сессияи сӯҳбат бо server лозим аст. Ҳама чизе, ки якҷоя кардани он боқӣ мемонад: Рӯйхати зерин нишон медиҳад, ки чӣ тавр муштарӣ ба server пайваст мешавад, ба он як паём мефиристад ва server дар навбати худ тасдиқ мекунад, ки паёмро бо истифода аз он ҳамчун далел дар худ қабул кардааст: "Сервер. java"
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    private static Socket clientSocket; // socket for communication
    private static ServerSocket server; // server socket
    private static BufferedReader in; // socket read stream
    private static BufferedWriter out; // socket write stream

    public static void main(String[] args) {
        try {
            try  {
                server = new ServerSocket(4004); // server socket listening on port 4004
                System.out.println("Server is running!"); // server would be nice
                // announce your launch
                clientSocket = server.accept(); // accept() will wait until
                //someone won't want to connect
                try { // after establishing a connection and recreating the socket for communication with the client, you can go
                    // to create I/O streams.
                    // now we can receive messages
                    in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                    // and send
                    out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

                    String word = in.readLine(); // wait for the client to write something to us
                    System.out.println(word);
                    // without hesitation responds to the client
                    out.write("Hi, this is the Server! I confirm you wrote: " + word + "\n");
                    out.flush(); // push everything out of the buffer

                } finally { // in any case, the socket will be closed
                    clientSocket.close();
                    // streams would also be nice to close
                    in.close();
                    out.close();
                }
            } finally {
                System.out.println("Server closed!");
                    server.close();
            }
        } catch (IOException e) {
            System.err.println(e);
        }
    }
"Client.java"
import java.io.*;
import java.net.Socket;

public class Client {

    private static Socket clientSocket; // socket for communication
    private static BufferedReader reader; // we need a reader that reads from the console, otherwise
    // do we know what the client wants to say?
    private static BufferedReader in; // socket read stream
    private static BufferedWriter out; // socket write stream

    public static void main(String[] args) {
        try {
            try {
                // address - local host, port - 4004, same as the server
                clientSocket = new Socket("localhost", 4004); // with this line we request
                // the server has access to the connection
                reader = new BufferedReader(new InputStreamReader(System.in));
                // read messages from the server
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                // write there
                out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

                System.out.println("Did you have something to say? Enter it here:");
                // if the connection happened and the threads were successfully created - we can
                // work further and offer the client something to enter
                // if not, an exception will be thrown
                String word = reader.readLine(); // wait for the client to do something
                // will not write to the console
                out.write(word + "\n"); // send a message to the server
                out.flush();
                String serverWord = in.readLine(); // wait for the server to say
                System.out.println(serverWord); // received - display
            } finally { // in any case, you need to close the socket and streams
                System.out.println("The client has been closed...");
                clientSocket.close();
                in.close();
                out.close();
            }
        } catch (IOException e) {
            System.err.println(e);
        }

    }
}
Албатта, шумо бояд аввал serverро оғоз кунед, зеро муштарӣ ҳангоми оғозёбӣ ба чӣ пайваст мешавад, агар чизе набошад, ки онро пайваст мекунад? :) Натиҷа чунин хоҳад буд: /* Шумо чизе гуфтан мехостед? Онро дар ин ҷо ворид кунед: Салом, server? Маро мешунавед? Салом, ин server аст! Ман тасдиқ мекунам, шумо навиштед: Салом, server? Маро мешунавед? Мизочон баста шуд... */ Оре! Мо ба server таълим додем, ки бо муштарӣ муошират кунад! Барои он ки муошират на дар ду реплика, балки ҳар қадаре, ки шумо мехоҳед, ба амал ояд, хондан ва навиштани риштаҳоро дар як ҳалқаи муваққатӣ (ҳақиқӣ) печонед ва барои баромадан нишон диҳед, ки мувофиқи як паёми муайян, масалан, "хуруҷ" , цикл катъ гардид ва программа ба охир мерасид. Сарвари Ҳафт: Корбари бисёрҷониба беҳтар аст Далели он, ки server моро мешунавад, хуб аст, аммо беҳтар мебуд, агар мо бо ягон нафари худамон муошират кунем. Ман ҳамаи манбаъҳоро дар охири мақола замима хоҳам кард, аз ин рӯ дар ин ҷо ман на ҳамеша калон, балки қисмҳои муҳими рамзҳоро нишон медиҳам, ки дар сурати дуруст истифода бурдани сӯҳбати бисёркорбарон имкон медиҳад. Ҳамин тавр, мо мехоҳем, ки тавассути server бо ягон муштарии дигар муошират кунем. Чӣ тавр бояд кард? Аён аст, ки барномаи муштарӣ усули худро дорад main, ин маънои онро дорад, ки онро аз server алоҳида ва дар баробари дигар муштариён оғоз кардан мумкин аст. Ин ба мо чӣ медиҳад? Ба ҳар ҳол, зарур аст, ки бо ҳар як пайвасти нав server фавран ба иртибот намеравад, балки ин пайвастро ба ягон рӯйхат менависад ва интизори пайвасти навро идома медиҳад ва як намуди хидматрасонии ёрирасон бо алоқаи мушаххас машғул аст. муштарӣ. Ва муштариён бояд ба server бинависанд ва новобаста аз ҳамдигар посухро интизор шаванд. Риштаҳо ба наҷот меоянд. Фарз мекунем, ки мо синфе дорем, ки барои дар хотир нигоҳ доштани пайвастҳои нав масъул аст: Он бояд дорои инҳо бошад:
  1. Рақами порт.
  2. Рӯйхате, ки дар он пайвасти нав менависад.
  3. Ва ServerSocket, дар як нусха (!).
public class Server {

    public static final int PORT = 8080;
    public static LinkedList<ServerSomthing> serverList = new LinkedList<>(); // list of all threads

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(PORT);
            try {
            while (true) {
                // Blocks until a new connection is made:
                Socket socket = server.accept();
                try {
                    serverList.add(new ServerSomthing(socket)); // add a new connection to the list
                } catch (IOException e) {
                    // If it fails, the socket is closed,
                    // otherwise, the thread will close it when it exits:
                    socket.close();
                }
            }
        } finally {
            server.close();
        }
    }
}
Хуб, акнун ҳар як розеткаи аз нав сохташуда гум намешавад, балки дар server нигоҳ дошта мешавад. Минбаъд. Ҳар як муштарӣ бояд касеро гӯш кунад. Биёед бо функсияҳои server аз боби охирин ришта эҷод кунем.
class ServerSomthing extends Thread {

    private Socket socket; // socket through which the server communicates with the client,
    // except for it - the client and server are not connected in any way
    private BufferedReader in; // socket read stream
    private BufferedWriter out; // socket write stream

    public ServerSomthing(Socket socket) throws IOException {
        this.socket = socket;
        // если потоку ввода/вывода приведут к генерированию исключения, оно пробросится дальше
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        start(); // call run()
    }
    @Override
    public void run() {
        String word;
        try {

            while (true) {
                word = in.readLine();
                if(word.equals("stop")) {
                    break;                }
                for (ServerSomthing vr : Server.serverList) {
                    vr.send(word); // send the received message with
                   // bound client to everyone else including him
                }
            }

        } catch (IOException e) {
        }
    }

    private void send(String msg) {
        try {
            out.write(msg + "\n");
            out.flush();
        } catch (IOException ignored) {}
    }
}
Ҳамин тавр, дар созандаи риштаи server розетка бояд оғоз карда шавад, ки тавассути он ришта бо муштарии мушаххас муошират мекунад. Инчунин риштаҳои I/O, ва ҳама чизҳои дигаре, ки ба шумо лозим аст, ки риштаро мустақиман аз созанда оғоз кунед. Хуб, аммо вақте ки риштаи server паёми муштариро мехонад, чӣ мешавад? Танҳо ба муштарии худ баргардонед? На он қадар самаранок. Мо сӯҳбати бисёр-корбарро анҷом медиҳем, аз ин рӯ ба ҳар як муштарии пайвастшуда лозим аст, то он чизеро, ки як нафар навиштааст, бигирад. Шумо бояд рӯйхати ҳамаи риштаҳои serverро, ки бо мизоҷони онҳо алоқаманданд, истифода баред ва ҳар як паёми ба риштаи мушаххас фиристодашударо фиристед, то он ба муштарии худ фиристад:
for (ServerSomthing vr : Server.serverList) {
    vr.send(word); // send the received message
    // from the linked client to everyone else, including him
}
private void send(String msg) {
    try {
        out.write(msg + "\n");
        out.flush();
    } catch (IOException ignored) {}
}
Акнун ҳама муштариён хоҳанд донист, ки яке аз онҳо чӣ гуфт! Агар шумо нахоҳед, ки паём ба шахси ирсолкарда фиристода шавад (ӯ аллакай медонад, ки чӣ навиштааст!), танҳо ҳангоми такрори риштаҳо, муайян кунед, ки ҳангоми коркарди an object, ҳалқа thisбидуни иҷроиш ба элементи дигар мегузарад. ҳама гуна амалҳо оид ба он. Ё, агар шумо хоҳед, ба муштарӣ паём фиристед, ки паём бомуваффақият қабул ва фиристода шудааст. Ҳама чиз бо server равшан аст. Биёед ба муштарӣ, дурусттараш ба мизоҷон гузарем! Дар он ҷо ҳама чиз якхела аст, аз рӯи шабеҳи муштарӣ аз боби охирин, танҳо ҳангоми сохтани як мисол ба шумо лозим аст, ки дар ин боб бо server нишон дода шудааст, ҳама чизро дар конструктор эҷод кунед. Аммо чӣ мешавад, агар ҳангоми эҷод кардани муштарӣ ӯ то ҳол вақти ворид кардани чизе надошта бошад, аммо чизе ба ӯ аллакай фиристода шуда бошад? (Масалан, таърихи мукотибаи онхое, ки пеш аз у ба чат пайвастанд). Ҳамин тавр, давраҳое, ки дар онҳо паёмҳои ирсолшуда коркард мешаванд, бояд аз давраҳое ҷудо карда шаванд, ки дар онҳо паёмҳо аз консол хонда мешаванд ва барои интиқол ба дигарон ба server фиристода мешаванд. Риштаҳо боз ба наҷот меоянд. Эҷоди муштарӣ ҳамчун ришта ҳеҷ маъно надорад. Дар усули иҷро сохтани ришта бо ҳалқа қулайтар аст, ки паёмҳоро мехонад ва инчунин аз рӯи қиёс менависад:
// thread reading messages from the server
private class ReadMsg extends Thread {
    @Override
    public void run() {

        String str;
        try {
            while (true) {
                str = in.readLine(); // waiting for a message from the server
                if (str.equals("stop")) {

                    break; // exit the loop if it's "stop"
                }
                            }
        } catch (IOException e) {

        }
    }
}
// thread sending messages coming from the console to the server
public class WriteMsg extends Thread {

    @Override
    public void run() {
        while (true) {
            String userWord;
            try {
               userWord = inputUser.readLine(); // messages from the console
                if (userWord.equals("stop")) {
                    out.write("stop" + "\n");
                    break; // exit the loop if it's "stop"
                } else {
                    out.write(userWord + "\n"); // send to the server
                }
                out.flush(); // clean up
            } catch (IOException e) {

            }

        }
    }
}
Дар созандаи муштарӣ ба шумо танҳо лозим аст, ки ин риштаҳоро оғоз кунед. Чӣ тавр бояд захираҳои муштариро дуруст пӯшанд, агар ӯ мехоҳад тарк кунад? Оё ман бояд захираҳои риштаи serverро пӯшам? Барои ин ба шумо лозим меояд, ки усули алоҳидаеро эҷод кунед, ки ҳангоми баромадан аз ҳалқаи паём даъват карда мешавад. Дар он ҷо ба шумо лозим меояд, ки розетка ва ҷараёнҳои I/O-ро пӯшед. Як сигнали анҷоми сессия барои муштарии мушаххас бояд ба риштаи serverи он фиристода шавад, ки он бояд бо розеткаи худ ҳамин тавр кунад ва худро аз рӯйхати риштаҳои синфи serverи асосӣ хориҷ кунад. Сарвари ҳаштум: Барои комorят маҳдудият вуҷуд надорад, Шумо метавонед беохир хусусиятҳои навро барои такмил додани лоиҳаи худ ихтироъ кунед. Аммо ба муштарии нав пайвастшуда чӣ бояд интиқол дода шавад? Ба фикрам дах вокеаи охир пеш аз омадани у руй дода буд. Барои ин, шумо бояд синферо эҷод кунед, ки дар он амали охирин бо ягон риштаи server ба рӯйхати эълоншуда ворид карда мешавад ва агар рӯйхат аллакай пур бошад (яъне 10 адад мавҷуд аст), якумро нест кунед ва илова кунед охирине, ки омад. Барои он ки мундариҷаи ин рӯйхат тавассути пайвасти нав қабул карда шавад, ҳангоми сохтани риштаи server, дар ҷараёни баромад, шумо бояд онҳоро ба муштарӣ фиристед. Чӣ тавр бояд кард? Масалан, ба ин монанд:
public void printStory(BufferedWriter writer) {
// ...
}
Риштаи server аллакай ҷараёнҳоро эҷод кардааст ва метавонад ҷараёни баромадро ҳамчун далел гузаронад. Баъдан, ба шумо танҳо лозим аст, ки ҳама чизеро, ки бояд ба муштарии нав дар давраи ҷустуҷӯ интиқол дода шавад, гузаронед. Хулоса: Ин танҳо асосҳост ва эҳтимоли зиёд ин меъмории чат ҳангоми сохтани як барномаи воқеӣ кор намекунад. Ин барнома барои мақсадҳои таълимӣ сохта шудааст ва дар асоси он ман нишон додам, ки чӣ тавр шумо метавонед муштариро бо server муошират кунед (ва баръакс), чӣ гуна ин корро барои якчанд пайвастҳо анҷом диҳед ва албатта, ин дар розеткаҳо чӣ гуна ташкил карда мешавад. Сарчашмаҳо дар зер ҷойгир карда шудаанд ва рамзи сарчашмаи барномаи таҳлилшаванда низ замима карда мешавад. Ин аввалин таҷрибаи ман дар навиштани мақола аст) Ташаккур барои таваҷҷӯҳ :)
  1. Фикр кардан дар Java Enterprise, аз ҷониби Брюс Эккел et. Ал. 2003
  2. Java 8, Роҳнамои мукаммал, Ҳерберт Шилдт, нашри 9, 2017 (Боби 22)
  3. Барномасозии розеткаҳо дар Java мақола дар бораи розеткаҳо
  4. Розетка дар ҳуҷҷатҳои расмӣ
  5. ServerSocket дар ҳуҷҷатҳои расмӣ
  6. манбаъҳо дар GitHub
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION