А.В. Столяров - Введение в операционные системы (1114673), страница 27
Текст из файла (страница 27)
Ïîëå sin_addr ñàìî ÿâëÿåòñÿ ñòðóêòóðîé,èìåþùåé ëèøü îäíî ïîëå ñ èìåíåì s_addr, êîòîðîå õðàíèò ip-àäðåñ ââèäå áåççíàêîâîãî ÷åòûðåõáàéòíîãî öåëîãî. ñåìåéñòâå AF_UNIX èñïîëüçóåòñÿ ñòðóêòóðà struct sockaddr_un, â êîòîðîé ìîæíî õðàíèòü èìÿ ôàéëà. Ýòà ñòðóêòóðà ñîñòîèò èç äâóõ ïîëåé:• sun_family − îáîçíà÷àåò ñåìåéñòâî àäðåñàöèè (â äàííîì ñëó÷àå çíà÷åíèå ýòîãî ïîëÿ äîëæíî áûòü óñòàíîâëåíî â AF_UNIX).• sun_path − ìàññèâ íà 108 ñèìâîëîâ, â êîòîðûé íåïîñðåäñòâåííî çàïèñûâàåòñÿ ñòðîêà èìåíè ôàéëà.Âûçîâ bind() âîçâðàùàåò 0 â ñëó÷àå óñïåõà, -1 â ñëó÷àå îøèáêè. Ó÷òèòå, ÷òî ñóùåñòâóåò ìíîæåñòâî ñèòóàöèé, â êîòîðûõ âûçîâ bind() ìîæåò íåïðîéòè; íàïðèìåð, îøèáêà ïðîèçîéäåò â ñëó÷àå ïîïûòêè èñïîëüçîâàíèÿ ïðèâèëåãèðîâàííîãî íîìåðà ïîðòà (îò 1 äî 1023) èëè ïîðòà, êîòîðûé íà äàííîéìàøèíå óæå êåì-òî çàíÿò (âîçìîæíî, äðóãîé âàøåé ïðîãðàììîé). Ïîýòîìóîáðàáîòêà îøèáîê ïðè âûçîâå bind() îñîáåííî âàæíà.Êðîìå âûçîâà bind() ñòðóêòóðû òèïîâ sockaddr_XXX èñïîëüçóþòñÿ âîìíîãèõ äðóãèõ ñëó÷àÿõ: âåçäå, ãäå íåîáõîäèìî çàäàòü àäðåñ ñîêåòà.23.4Ïðèåì è ïåðåäà÷à äåéòàãðàììÐàññìîòðèì ðàáîòó ñ ñîêåòàìè äåéòàãðàììíîãî òèïà.Ñîêåò ñîçäàåòñÿ âûçîâîì socket() ñ óêàçàíèåì êîíñòàíòû SOCK_DGRAM âêà÷åñòâå âòîðîãî ïàðàìåòðà.
Æåëàòåëüíî ñâÿçàòü ñîêåò ñ êîíêðåòíûì àäðåñîì ñ ïîìîùüþ bind(), â ïðîòèâíîì ñëó÷àå ñ ñîêåòà ìîæíî áóäåò îòïðàâëÿòüäàííûå (ñèñòåìà ñàìà âûáåðåò îäèí èç ñâîèõ àäðåñîâ è ïîðòîâ â êà÷åñòâåàäðåñà îòïðàâèòåëÿ), íî íå áóäåò âîçìîæíîñòè ïîëó÷èòü îòâåò.Ïîñëå òîãî, êàê ñîêåò ñîçäàí è ñâÿçàí ñ àäðåñîì, äëÿ ïåðåäà÷è è ïðèåìàäàííûõ ìîæíî èñïîëüçîâàòü ñèñòåìíûå âûçîâû sendto() è recvfrom():3 Íàçâàíèåôóíêöèè htons() ïîëó÷åíî êàê ñîêðàùåíèå îò Host to Network Short, ò.å. ïðåîáðàçîâàíèå èçõîñòîâîãî â ñåòåâîé ïîðÿäîê áàéò äëÿ êîðîòêîãî öåëîãî.
Áîëåå ïîäðîáíî ïîíÿòèå ñåòåâîãî ïîðÿäêà áàéòáóäåò ðàññìîòðåíî íèæå.124int sendto(int s, const void *buf, int len, int flags,const struct sockaddr *to, socklen_t tolen);int recvfrom(int s, void *buf, int len, int flags,struct sockaddr *from, socklen_t *fromlen); îáîèõ âûçîâàõ ïàðàìåòð s çàäàåò äåñêðèïòîð ñîêåòà, buf óêàçûâàåò íàáóôåð, ñîäåðæàùèé äàííûå äëÿ ïåðåäà÷è ëèáî ïðåäíàçíà÷åííûé äëÿ ðàçìåùåíèÿ ïðèíÿòûõ äàííûõ, len óñòàíàâëèâàåò ðàçìåð ýòîãî áóôåðà (ñîîòâåòñòâåííî, êîëè÷åñòâî äàííûõ, ïîäëåæàùèõ ïðèåìó èëè ïåðåäà÷å). Ïàðàìåòðflags èñïîëüçóåòñÿ äëÿ óêàçàíèÿ äîïîëíèòåëüíûõ îïöèé; äëÿ íîðìàëüíîéðàáîòû îáû÷íî äîñòàòî÷íî óêàçàòü çíà÷åíèå 0. âûçîâå sendto() ïàðàìåòð to óêàçûâàåò íà ñòðóêòóðó, ñîäåðæàùóþàäðåñ ñîêåòà, íà êîòîðûé íåîáõîäèìî îòïðàâèòü äàííûå (òî åñòü àäðåñ ïîëó÷àòåëÿ ñîîáùåíèÿ).
ßñíî, ÷òî èñïîëüçóåòñÿ ïðè ýòîì ñòðóêòóðà òèïà, ñîîòâåòñòâóþùåãî èçáðàííîìó ñåìåéñòâó àäðåñàöèè (sockaddr_in äëÿ AF_INET èsockaddr_un äëÿ AF_UNIX). Ïàðàìåòð tolen äîëæåí áûòü ðàâåí ðàçìåðó ýòîéñòðóêòóðû. Òèï socklen_t îáû÷íî ÿâëÿåòñÿ ñèíîíèìîì òèïà int. âûçîâå recvfrom() ïàðàìåòð from óêàçûâàåò íà ñòðóêòóðó, â êîòîðóþâûçîâó ñëåäóåò çàïèñàòü àäðåñ îòïðàâèòåëÿ ïîëó÷åííîãî ïàêåòà (ò.å. òàêèìîáðàçîì ìîæíî óçíàòü, îòêóäà ïàêåò ïðèøåë). Ïàðàìåòð fromlen ïðåäñòàâëÿåò ñîáîé óêàçàòåëü íà ïåðåìåííóþ òèïà socklen_t, ïðè÷åì ïåðåä âûçîâîìrecvfrom() â ýòó ïåðåìåííóþ ñëåäóåò çàíåñòè ðàçìåð àäðåñíîé ñòðóêòóðû,íà êîòîðóþ óêàçûâàåò ïðåäûäóùèé ïàðàìåòð; ïîñëå âîçâðàòà èç recvfrom()ïåðåìåííàÿ áóäåò ñîäåðæàòü êîëè÷åñòâî áàéò, êîòîðûå âûçîâ â èòîãå â ýòóñòðóêòóðó çàïèñàë.Ñëåäóåò îòìåòèòü, ÷òî ïðè ðàáîòå ïî ñåòè Èíòåðíåò äëÿ ïåðåäà÷è äåéòàãðàìì èñïîëüçóåòñÿ ïðîòîêîë UDP.
Îñîáåííîñòè ñâÿçêè IP/UDP òàêîâû, ÷òî ïåðåäàí ìîæåò áûòü òîëüêî ïàêåòîãðàíè÷åííîãî ðàçìåðà, ïðè÷åì êîíêðåòíûé ðàçìåð, âîîáùå ãîâîðÿ, ìîæåò îêàçàòüñÿ ðàçëè÷íûì äëÿ ðàçëè÷íûõ àäðåñîâ ïîëó÷àòåëåé. Èòîãîì ýòîãî îáñòîÿòåëüñòâà ÿâëÿþòñÿ äîñòàòî÷íîñëîæíûå ïðîöåäóðû äèíàìè÷åñêîãî îïðåäåëåíèÿ äîïóñòèìîãî ðàçìåðà ïàêåòà; îïèñàíèå ýòèõïðîöåäóð âûõîäèò çà ðàìêè íàøåãî êóðñà. Ïðè æåëàíèè ÷èòàòåëü ìîæåò ñàìîñòîÿòåëüíî èçó÷èòü èõ, îáðàòèâøèñü, íàïðèìåð, ê êíèãå [6].23.5Ïîòîêîâûå ñîêåòû.
Êëèåíò-ñåðâåðíàÿ ìîäåëüÏðè âçàèìîäåéñòâèè ñ ïîìîùüþ ïîòîêîâûõ ñîêåòîâ íåîáõîäèìî ïåðåä íà÷àëîì âçàèìîäåéñòâèÿ óñòàíîâèòü ñîåäèíåíèå. ßñíî, ÷òî åñëè ðå÷ü èäåò îâçàèìîäåéñòâèè íåðîäñòâåííûõ ïðîöåññîâ, è òåì áîëåå î âçàèìîäåéñòâèè ïðîöåññîâ, íàõîäÿùèõñÿ íà ðàçíûõ ìàøèíàõ, îäèí èç ó÷àñòíèêîâ âçàèìîäåéñòâèÿäîëæåí áûòü èíèöèàòîðîì ñîåäèíåíèÿ, à âòîðîé − ïðèíÿòü ñîåäèíåíèå (ñîãëàñèòüñÿ íà åãî óñòàíîâëåíèå).125запрос соединенияLСерверLКлиентСерверииненсоедеКлиентÐèñ.
23: Óñòàíîâëåíèå ñîåäèíåíèÿ ìåæäó ïîòîêîâûìè ñîêåòàìèÇäåñü ìû ñòàëêèâàåìñÿ ñ ïîíÿòèÿìè êëèåíòà è ñåðâåðà. Ïîä ñåðâå-ïîíèìàåòñÿ ïðîãðàììà, îæèäàþùàÿ çàïðîñîâ è ïðîèçâîäÿùàÿêàêèå-ëèáî äåéñòâèÿ èñêëþ÷èòåëüíî â îòâåò íà çàïðîñû, à ïðè îòñóòñòâèè çàïðîñîâ íå äåëàþùàÿ âîîáùå íè÷åãî. Ñîîòâåòñòâåííî,ïîä êëèåíòîì ïîíèìàåòñÿ ïðîãðàììà, îáðàùàþùàÿñÿ ñ çàïðîñîìê ñåðâåðó4 .ðîìÏðè óñòàíîâëåíèè ñîåäèíåíèÿ ìåæäó ïîòîêîâûìè ñîêåòàìè îäèí ïðîöåññîæèäàåò çàïðîñà íà óñòàíîâëåíèå ñîåäèíåíèÿ, à äðóãîé èíèöèèðóåò òàêîé çàïðîñ.
Ýòè ïðîöåññû è íàçûâàþòñÿ ñ òî÷êè çðåíèÿ óñòàíîâëåíèÿ ñîåäèíåíèÿñåðâåðîì è êëèåíòîì; â ÷àñòíîñòè, ïðè ðàáîòå ïî ñåòè Èíòåðíåò äëÿ îðãàíèçàöèè âçàèìîäåéñòâèÿ ïîòîêîâûõ ñîêåòîâ èñïîëüçóåòñÿ ïðîòîêîë TCP, àñîîòâåòñòâóþùèå ïðîãðàììû íàçûâàþòñÿ TCP-ñåðâåðîì è TCP-êëèåíòîì.23.5.1Îðãàíèçàöèÿ ñåðâåðà×òîáû íà÷àòü îæèäàíèå çàïðîñîâ íà ñîåäèíåíèå, ñåðâåð ñîçäàåò ñîêåò ñîîòâåòñòâóþùåãî òèïà, ñâÿçûâàåò åãî ñ àäðåñîì è ïåðåâîäèò â ñïåöèàëüíîåñîñòîÿíèå, íàçûâàåìîå ñëóøàþùèì (àíãë.
listening). Íà ñîêåòå, íàõîäÿùåìñÿâ ñëóøàþùåì ñîñòîÿíèè, ìîæåò áûòü îñóùåñòâëåíà òîëüêî îäíà îïåðàöèÿ −ïðèíÿòèå ñîåäèíåíèÿ. Ïðè óñòàíîâëåíèè ñîåäèíåíèÿ ÿäðî îïåðàöèîííîé ñèñòåìû, êîòîðàÿ îáñëóæèâàåò ïðîãðàììó-ñåðâåð, ñîçäàåò åùå îäèí ñîêåò, êîòîðûé è áóäåò èñïîëüçîâàòüñÿ äëÿ ïåðåäà÷è äàííûõ ïî òîëüêî ÷òî óñòàíîâëåííîìó ñîåäèíåíèþ (ðèñ. 23).Èòàê, íà ñòîðîíå ñåðâåðà ñîêåò íåîáõîäèìî ñîçäàòü âûçîâîì socket() ññîîòâåòñòâóþùèìè ïàðàìåòðàìè è ñâÿçàòü åãî ñ êîíêðåòíûì àäðåñîì, íà êîòîðîì áóäóò ïðèíèìàòüñÿ ñîåäèíåíèÿ, ñ ïîìîùüþ âûçîâà bind().
Çàòåì ñîêåòñëåäóåò ïåðåâåñòè â ñëóøàþùèé ðåæèì (íà ðèñ. 23 ñëóøàþùèé ñîêåò îáîçíà÷åí áóêâîé L) ñ ïîìîùüþ âûçîâà4 Âîîáùåãîâîðÿ, îäíà è òà æå ïðîãðàììà ìîæåò âûïîëíÿòü ôóíêöèè ñåðâåðà ïî îòíîøåíèþ ê îäíèìïðîãðàììàì è êëèåíòà − ïî îòíîøåíèþ ê äðóãèì, åñëè äëÿ óäîâëåòâîðåíèÿ çàïðîñà êëèåíòà ñåðâåðóíåîáõîäèìî âîñïîëüçîâàòüñÿ óñëóãàìè äðóãîãî ñåðâåðà126int listen(int sd, int qlen);Ïàðàìåòð sd − ñâÿçàííûé ñ ñîêåòîì ôàéëîâûé äåñêðèïòîð. Ïàðàìåòð qlençàäàåò ðàçìåð î÷åðåäè íåïðèíÿòûõ çàïðîñîâ íà ñîåäèíåíèå. Ïîÿñíèì ýòî. Äîïóñòèì, ìû ïåðåâåëè ñîêåò â ñëóøàþùèé ðåæèì, è íåñêîëüêî êëèåíòîâ óæåîòïðàâèëè íàì çàïðîñû íà ñîåäèíåíèå, íî â ñèëó òåõ èëè èíûõ ïðè÷èí ìûíåêîòîðîå âðåìÿ íå ïðèíèìàåì ýòè çàïðîñû (òî åñòü íå âûïîëíÿåì ñîîòâåòñòâóþùóþ îïåðàöèþ ñî ñëóøàþùèì ñîêåòîì).
Âîçìîæíîñòè ñèñòåìû ïî õðàíåíèþ íåîáðàáîòàííûõ çàïðîñîâ îãðàíè÷åíû. Ïåðâûå qlen çàïðîñîâ áóäóòîæèäàòü ïðèíÿòèÿ ñîåäèíåíèÿ, åñëè æå ñèñòåìà ïîëó÷èò åùå çàïðîñû, îíèáóäóò îòêëîíåíû. Ñëåäóåò îñîáî ïîä÷åðêíóòü, ÷òî ïàðàìåòð qlen íå èìååòíèêàêîãî îòíîøåíèÿ ê îáùåìó êîëè÷åñòâó ñîåäèíåíèé ñ êëèåíòàìè. Îáû÷íî â êà÷åñòâå ïàðàìåòðà qlen ïåðåäàþò ÷èñëî 5, ïîñêîëüêó íåêîòîðûå ÿäðàîïåðàöèîííûõ ñèñòåì íå ïîçâîëÿþò ñîçäàâàòü î÷åðåäü áîëüøåãî ðàçìåðà, àìåíüøàÿ î÷åðåäü ìîæåò îêàçàòüñÿ íåäîñòàòî÷íîé.Ïðèíÿòèå ñîåäèíåíèÿ ïðîèçâîäèòñÿ âûçîâîìint accept(int sd, struct sockaddr *addr, socklen_t *addrlen);Ïàðàìåòð sd çàäàåò äåñêðèïòîð ñëóøàþùåãî ñîêåòà.
Ïàðàìåòð addr óêàçûâàåò íà ñòðóêòóðó, â êîòîðóþ ñëåäóåò çàïèñàòü àäðåñ ñîêåòà, ñ êîòîðûì óñòàíîâëåíî ñîåäèíåíèå (èíà÷å ãîâîðÿ, àäðåñ äðóãîãî êîíöà ñîåäèíåíèÿ). Ïàðàìåòðaddrlen ïðåäñòàâëÿåò ñîáîé óêàçàòåëü íà ïåðåìåííóþ òèïà socklen_t, ïðè÷åì ïåðåä âûçîâîì accept() â ýòó ïåðåìåííóþ ñëåäóåò çàíåñòè ðàçìåð àäðåñíîé ñòðóêòóðû, íà êîòîðóþ óêàçûâàåò ïðåäûäóùèé ïàðàìåòð; ïîñëå âîçâðàòàèç accept() ïåðåìåííàÿ áóäåò ñîäåðæàòü êîëè÷åñòâî áàéò, êîòîðûå âûçîâ âèòîãå â ýòó ñòðóêòóðó çàïèñàë. Ýòî àíàëîãè÷íî ïàðàìåòðàì from è fromlenâ âûçîâå recvfrom().Âûçîâ accept() âîçâðàùàåò ôàéëîâûé äåñêðèïòîð íîâîãî ñîêåòà, ñîçäàííîãî ñïåöèàëüíî äëÿ îáñëóæèâàíèÿ âíîâü óñòàíîâëåííîãî ñîåäèíåíèÿ (ëèáî-1 â ñëó÷àå îøèáêè). Åñëè íà ìîìåíò âûïîëíåíèÿ accept() çàïðîñîâ íà ñîåäèíåíèå åùå íå ïîñòóïèëî, âûçîâ áëîêèðóåò âûçâàâøèé ïðîöåññ è îæèäàåòïîñòóïëåíèÿ çàïðîñà íà ñîåäèíåíèå, âîçâðàùàÿ óïðàâëåíèå òîëüêî ïîñëå òîãî,êàê òàêîé çàïðîñ ïîñòóïèò, è ñîåäèíåíèå áóäåò óñòàíîâëåíî.Ñëåäóåò îòìåòèòü, ÷òî ñ ìîìåíòà ïðèíÿòèÿ ïåðâîãî ñîåäèíåíèÿ âïðîãðàììå-ñåðâåðå èìååòñÿ äâà äåñêðèïòîðà, òðåáóþùèõ îáðàáîòêè: äåñêðèïòîð ñëóøàþùåãî ñîêåòà, íà êîòîðîì ìîæíî ïðèíèìàòü íîâûå çàïðîñû íà ñîåäèíåíèÿ, è ñîêåò, ñîîòâåòñòâóþùèé ïðèíÿòîìó ñîåäèíåíèþ, ñ êîòîðîãî òðåáóåòñÿ ÷èòàòü ïðèøåäøèå îò êëèåíòà äàííûå (íàïðèìåð, òåêñò çàïðîñà).
Ýòîñîçäàåò ïðîáëåìó î÷åðåäíîñòè äàëüíåéøèõ äåéñòâèé. Ìû âåðíåìñÿ ê îáñóæäåíèþ ýòîé ïðîáëåìû íà ñëåäóþùåé ëåêöèè.12723.5.2Îðãàíèçàöèÿ êëèåíòàÊëèåíòñêàÿ ïðîãðàììà äîëæíà, êàê è ñåðâåð, ñîçäàòü ñîêåò âûçîâîìsocket(). Ñâÿçûâàòü ñîêåò ñ êîíêðåòíûì àäðåñîì íå îáÿçàòåëüíî; åñëè ýòîãîíå ñäåëàòü, ñèñòåìà âûáåðåò àäðåñ àâòîìàòè÷åñêè.Çàïðîñ íà ñîåäèíåíèå ôîðìèðóåòñÿ âûçîâîìint connect(int sd, struct sockaddr *addr, int addrlen);Ïàðàìåòð sd − ñâÿçàííûé ñ ñîêåòîì ôàéëîâûé äåñêðèïòîð. Ïàðàìåòð addróêàçûâàåò íà ñòðóêòóðó, ñîäåðæàùóþ àäðåñ ñåðâåðà (ò.å.