Johdatus verkko toiminnot C

Link: http://shoe.bocks.com/net/

Sisältö

  • Käyttöönotto
  • Luoda socket
  • Sitovat a socket-portti
  • Kuuntelee yhteyksiä
  • Hyväksyä yhteys
  • Sulkemalla yhteydet
  • tietojen Lähettäminen yhteys
  • Vastaanottaa tietoja yhteys
  • Asetus socket vaihtoehtoja
  • Käsittely on enemmän kuin yksi yhteys
  • Muuntaa hostname osaksi verkko-osoite
  • Vahvistetaan lähtevä yhteys
  • Muutokset opetusohjelma
  • Lataa koko opetusohjelma (.tar.gz)
  • Lataa koko opetusohjelma (.zip)
  • Tarkastele tiedostoja out of my network library
  • Lataa my network library
  • Linkki sanasto

© Copyright 1996-2013 Simon Amor

Johdanto

Tässä opetusohjelmassa, aion yrittää selittää käyttää ja syntaksi joitakin perus UNIX verkostoitumisen toimintoja C. Jos haluat tietää enemmän siitä, Windows Sockets ohjelmointi, pelkään WinSock resurssit StarDust on kadonnut nyt – mitään viitteitä samankaltaisia sivuja olisi tervetullutta!

Saatat myös haluta tarkistaa Internet-ohjelmointi-tehokurssi. Voit myös vierailla Verkostoituminen ABC Kaikki Verkostoituminen, 2 tietokoneen home networking XP verkostoituminen.

On joitakin, esimerkiksi ohjelmia, jotka selitän, miten kirjoittaa alusta alkaen. Jos haluat tietää enemmän toiminta, saatat on-line manual pages (käytä ‘mies-toiminto’) tai järjestelmän ylläpitäjät voivat antaa käsikirjat.

Voit tarkastella tai ladata source code mutta en voi taata, että se toimii kaikissa järjestelmissä, joten jos löydät kaikki koodi, joka ei toimi, ole hyvä ja sähköposti tiedot järjestelmän (Käyttöjärjestelmä, Arkkitehtuuri jne.) ja mikä ei toimi ja minä nähdä, jos voin korjata sen.

Olisin myös kiitollinen sähköpostia kertoo minulle, jos se EI toimi teidän järjestelmä (tai jos olet onnistunut muuttaa osia ja saada se toimimaan), jos voisitte lähettää sähköpostia muutoksia minua, en voi sitten sisällyttää muutokset osaksi lähdekoodia.
Joissakin ympäristöissä, jotka on testattu:

  • Linux-ytimen 2.2.x, gcc2
  • Linux-ytimen 2.4.x, gcc3
  • Mac OSX 10.3 – viittaukset malloc.s täytyy olla muuttunut sys/malloc.s ja sekä “ar”, sinun täytyy myös ajaa ‘ranlib’ library tiedoston libnet.(rakennettu network library-lähde)
  • HPUX – täytyy lisätä -lsocket kun yhdistää suoritettavan kuten alla on mainittu.

Joitakin versioita UNIX, esimerkiksi ohjelmat eivät linkki, valittavat asioita, kuten määrittelemättömiä symboleja sitoa, hyväksyä, kuunnella ja pistorasia.

Tällaisia virheitä tulee luultavasti näyttämään tältä:

Undefined                       first referenced
 symbol                             in file
socket                              /var/tmp/ccLkjMcu.o
accept                              /var/tmp/ccLkjMcu.o
bind                                /var/tmp/ccLkjMcu.o
listen                              /var/tmp/ccLkjMcu.o
ld: fatal: Symbol referencing errors. No output written to a.out

Tämä tarkoittaa yleensä sitä, että sinun pitäisi linkkiä ylimääräisiä kirjasto lisäämällä -lsocket kopio-riville.
Esimerkiksi: cc -o netapp netapp.c -lsocket

Tämä opetusohjelma oletetaan, että käyttäjä tietää, miten ohjelman C.

Jos löydät tämän opetusohjelman mitään etua lainkaan, ole hyvä ja ota yhteyttä ja ilmoita minulle. Se ei ole läheskään valmis vielä, mutta sähköpostia minulle joka tapauksessa, vaikka se olisi vain sanoa, “Hei! saada, että opetusohjelma valmis” 🙂
Takaisin sisältöön

Luo socket

Ensimmäinen asia tehdä on luoda socket jonka voit sitten manipuloida monin tavoin. Luoda liittimeen, voit käyttää socket () – funktiolla.

Includes:

#include <sys/types.h>
#include <sys/socket.h> 

Syntax:

int socket(int af, int type, int protocol);

C source:

int socket_desc;

  socket_desc=socket(AF_INET,SOCK_STREAM,0);
  if (socket_desc==-1)
    perror("Create socket");

socket() palauttaa socket avainsana, jota voidaan käyttää muiden verkon komentoja. Tämä luo socket, joka käyttää DARPA Internet-osoitteita, ja menetelmä yhteyden on tavu virta, joka on samanlainen putki. Vaihtoehto tavu puroihin on. datagram mutta tämä opetusohjelma ei kata niitä.
Palvelimia, ensimmäinen socket on luotu usein nimellä ” master pistorasiaan“. Ennen pistorasiaan voi lähettää tai vastaanottaa tietoja, sen täytyy olla liitetty toiseen pistorasiaan. Jos toimii master-pistorasiaan, se on sidottu. – portti numero niin, että asiakkaat voi tietää mistä “löytää” – liittimeen ja kytke se.
Jos onnistuu, socket() palauttaa voimassa oleva socket avainsana; muussa tapauksessa se palauttaa arvon -1 ja asettaa virheilmoitus ilmoittaa virheen. perror() tai strerror() voidaan käyttää kääntää virheilmoitus arvo osaksi ihmisen luettavissa merkkijono.

Sitova socket-portti

Perustaa master pistorasiaan, sinun täytyy sitoa socket avainsana on monin tavoin. Luoda liittimeen, voit käyttää socket () – funktio kuten edellä on kuvattu Luomalla socket.

Includes:

#include <sys/socket.h>
#include <netinet/in.h>

Syntax:

int bind(int s, struct sockaddr *addr, int addrlen);

C source:

struct sockaddr_in address;

/* type of socket created in socket() */
  address.sin_family = AF_INET;
  address.sin_addr.s_addr = INADDR_ANY;
/* 7000 is the port to use for connections */
  address.sin_port = htons(7000);
/* bind the socket to the port specified above */
  bind(socket_desc,(struct sockaddr *)&address,sizeof(address));

Jos onnistuu, bind() palauttaa 0; muussa tapauksessa se palauttaa arvon -1 ja asettaa virheilmoitus ilmoittaa virheen.
Määritetyn portin lähde koodi edellä (port 7000) on, jos palvelin voi olla yhteydessä. Testata tätä, käännä ohjelma `sockbind’ source code – hakemistoon ja suorita se. Kun se on käynnissä, kirjoita:

telnet localhost 7000

ja sinun pitäisi saada

Trying...

muutaman sekunnin ja sitten

telnet: Unable to connect to remote host: Connection refused

koska palvelin ohjelma päättyy. Tämä osoittaa, että palvelin oli ok. Jos yhteys on kieltäytyi välittömästi, on luultavasti ongelma palvelimen kanssa.

Kuuntelee yhteyksiä

Ennen kuin mitään yhteyksiä voidaan hyväksyä, pistorasia on kertonut kuuntelee yhteyksiä ja myös suurin määrä vireillä olevia yhteyksiä käyttäen listen()

Includes:

#include <sys/socket.h>

Syntax:

int listen(int s, int backlog);

C source:

  listen(socket_desc,3);

edellä rivi määrittää, että siellä voi olla jopa 3-yhteyksien kesken. Jos yhteys pyyntö saapuu, kun on jo 3 yhteydet odotettaessa, asiakas saa aikakatkaisu virhe.

listen() koskee vain kytkemättä pistorasiat tyyppi SOCK_STREAM. Jos pistorasia ei ole sidottu paikalliseen porttiin, ennen kuin kuunnella() on esitetty, järjestelmä automaattisesti sitoo paikallinen portti pistorasia kuunnella.
Jos onnistuu

, listen() returns 0; muutoin se palauttaa arvon -1 ja asettaa virheilmoitus ilmoittaa virheen.

Hyväksymällä yhteyden

Itse asiassa kertoa, että palvelin hyväksyy yhteyden, sinun täytyy käyttää toimintoa accept()

Includes:

#include <sys/socket.h>

Syntax:

int accept(int s, struct sockaddr *addr, int *addrlen);

C source:

int addrlen;
struct sockaddr_in address;

  addrlen = sizeof(struct sockaddr_in);
  new_socket = accept(socket_desc, (struct sockaddr *)&address, &addrlen);
  if (new_socket<0)
    perror("Accept connection");

accept() käytetään perustuva yhteys pistorasiat, kuten purot. Parametrit ovat socket avainsana master socket seuraa sockaddr_in rakenne ja koko rakenteen. Jos onnistuu, hyväksy() palauttaa positiivinen kokonaisluku, joka on socket avainsana hyväksyttyyn pistorasiaan. Jos tapahtuu virhe, -1 palautetaan ja errno-muuttuja on asetettu osoittamaan syy.

Siellä on joitakin esimerkki source code hakemistossa, ohjelma kääntää kutsutaan “hyväksy”, Kun se on käynnissä, kirjoita:

telnet localhost 7000

ja sinun pitäisi saada

Trying...
Connected to localhost.
Escape character is '^]'.

ja sitten 10 sekuntia myöhemmin, se pitäisi sulkea yhteyden. Jälleen kerran, jos yhteys on kieltäytyi välittömästi, on luultavasti ongelma palvelimen kanssa.

yhteyksien Sulkemista

Luultavasti yksi helpoimmista asioita voit tehdä kanssa pistorasiaan, joka on lähellä sitä. Tämä tehdään käyttämällä close()

Includes:

#include <unistd.h>

Syntax:

int close(int sockdes);

C source:

  close(new_socket);

close() sulkee socket avainsana merkitty sockdes.
Kun onnistuneesti päätökseen, close() palauttaa arvon 0, muuten se palauttaa arvon -1 ja asettaa virheilmoitus ilmoittaa virheen.

tietojen Lähettäminen yhteys

Hyväksy yhteys ei olisi mitään hyötyä ilman keinoja lähettää tai vastaanottaa tietoja. Lähettää ilman saada voisi käyttää tietoja palvelimelle, joka palauttaa aina kiinteä viesti.

Includes:

#include <sys/socket.h>
#include <string.h>

Syntax:

int send(int s, const void *msg, int len, int flags);

C source:

char *message="This is a message to send\n\r";

  send(new_socket,message,strlen(message),0);

Viestin pitäisi olla \n\r sijasta \n tai \r koska muuten teksti, joka näkyy joitakin asiakkaita voi tuntua oudolta. e.g teksti vain \n näyttäisi seuraavasti:

This is a message
                 and this is the second line
                                            and the third.

sen sijaan:

This is a message
and this is the second line
and the third.

send() käytetään lähettämään viesti toiseen pistorasiaan ja voidaan käyttää vain silloin, kun pistorasiaan on kytketty tilaan. Pistorasia avainsana, joka määrittää pistorasia, johon viesti lähetetään, on “s”, syntaksi edellä. ‘msg’ pistettä puskuriin, joka sisältää viestin, ja viestin pituus on antanut len tavua.
Tuetut arvot liput ovat nolla, tai MSG_OOB (lähettää out-of-band data) – write () – kutsun tehty socket käyttäytyy täsmälleen samalla tavalla kuin lähetä() liput nolla.
Kun onnistuneesti päätökseen, send() palauttaa tavujen lähetetään. Muuten, se palauttaa arvon -1 ja asettaa virheilmoitus osoittaa paikallisesti havaittu virhe. “Hyväksy” – ohjelma on muutettu lähettää tervetuloa-viesti-yhteys, ennen kuin se sulkee socket. Nähdä, miten tämä tehdään, katso source code ohjelma “lähetä”.

Vastaanottaa tietoja yhteyden

Hyväksy yhteys ei olisi mitään hyötyä ilman keinoja lähettää tai vastaanottaa tietoja. Saavat vain voi olla käytetty tiedonkeruun menetelmä.
Includes:

#include <sys/socket.h>

Syntax:

int recv(int s, void *msg, int len, int flags);

C source:

int bufsize=1024;        /* a 1K buffer */
char *buffer=malloc(bufsize);

  recv(new_socket,buffer,bufsize,0);

Liput parametri voidaan asettaa MSG_PEEK, MSG_OOB ja, sekä, tai nolla. Jos se on asetettu MSG_PEEK, kaikki tiedot palautetaan käyttäjälle vielä on käsitelty ikään kuin se ei ollut lukenut, en.e seuraavana recv() uudelleen lukee samat tiedot.
read () – kutsun tehty socket käyttäytyy aivan samalla tavalla kuin recv() liput nolla.
Jos onnistuu, v. otet() palauttaa vastaanotettujen tavujen määrä, muuten se palauttaa arvon -1 ja asettaa virheilmoitus ilmoittaa error. recv() palauttaa 0, jos pistorasia on estää ja yhteyden kauko solmu epäonnistui.

Asetus socket asetukset

Jotta tiettyjä socket toiminta vaatii manipulointi socket vaihtoehtoja käyttämällä not installed()

Includes:

#include <sys/socket.h>

Syntax:

  int setsockopt(int s, int level, int optname,
                 const void *optval, int optlen);

C source:

#define TRUE   1
#define FALSE  0

int socket_desc;     /* master socket returned by socket() */
int opt=TRUE;        /* option is to be on/TRUE or off/FALSE */

  setsockopt(socket_desc,SOL_SOCKET,SO_REUSEADDR,
              (char *)&opt,sizeof(opt));

SOL_SOCKET määrittää vaihtoehto on `socket taso’ vaihtoehto, nämä on määritelty <sys/socket.h>
pistorasia on merkitty socket avainsana s.
Vaihtoehto SO_REUSEADDR on voimassa vain AF_INET pistorasiat.
On olemassa kaksi erilaista vaihtoehtoa: boolean ja ei-boolean. Boolean vaihtoehdot ovat joko asetettu tai ei asetettu, ja voi myös käyttää optval ja optlen välittää tietoa. Ei-loogisia vaihtoehtoja aina käyttää optval ja optlen välittää tietoa.

Käsittely useamman kuin yhden yhteyden,

Jotta pistorasia voidaan lukea ilman, että odotetaan jos ei ole input, pistorasia on asetettava ei-esto käyttäen seuraavaa koodinpätkä.

fcntl(mastersocket, F_SETFL, FNDELAY);

tai

fcntl(mastersocket, F_SETFL, O_NONBLOCK);

Jos edellä palaa ei-nolla tulos, toiminta epäonnistui ja virheilmoitus tulee asettaa sopiva arvo.

Käyttämällä valitse seurata useita pistorasiat (tai vain yksi) on melko yksinkertainen, ja sitä on esitetty alla oleva koodi. Huomaa, että tämä on epätäydellinen koodin luominen master pistorasia ei ole mukana (ks. edellinen yksityiskohtia).

fd_set readfds;

/* create a list of sockets to check for activity */
FD_ZERO(&readfds);

/* specify mastersocket - ie listen for new connections */
FD_SET(mastersocket, &readfds);

/* wait for connection, forever if have to */
new_conns=select(max_conns, readfds, NULL, NULL, NULL);

if ((new_conns<0) && (errno!=EINTR)) {
  /* there was an error with select() */
}
if (FD_ISSET(mastersocket,&readfds)) {
  /* Open the new socket */
}

Tietenkin, edellä on vain odottaa toimintaa master pistorasiaan. Mitä sinun tarvitsee tehdä on ajaa se sisällä silmukan, joka toistaa kunnes palvelin suljetaan.
Äskettäin luotu pistorasiat on seurattava yhtä hyvin (ellei yhteydet hyväksytty, on suljettu sen jälkeen, kun outputing viesti).

Esimerkki tästä on kohdassa näyte ohjelma multi.c, joka hyväksyy enintään kolme yhteyksiä ja välittää tiedot yhdestä socket muille. Se on melkein hyvin yksinkertainen chat-palvelimeen.

Muuntaa hostname osaksi verkko-osoite

Includes:

#include <netdb.h>

Syntax:

  struct hostent *gethostbyname(const char *name);

C source:

  struct hostent *hent;

  hent = gethostbyname("www.foobar.net");

A hostent rakenne:

struct hostent {
    char    *h_name;        /* official name of host */
    char    **h_aliases;    /* alias list */
    int     h_addrtype;     /* host address type */
    int     h_length;       /* length of address */
    char    **h_addr_list;  /* list of addresses */
}

Jotkut verkon toiminnot vaativat rakenne, jossa verkko-osoite ja joskus portin numero liittää tai. Helpoin tapa muuntaa palvelimen nimi verkko-osoite on käyttää gethostbyname() – toiminto.

gethostbyname() palauttaa rakenteen tyyppi hostent – tämä rakenne sisältää palvelimen nimi, joukko vaihtoehtoisia nimiä ja myös erilaisia verkko-osoitteita (network byte order).

Perustamisesta lähtevä yhteys

Voit muodostaa yhteyden toiseen pistorasiaan (kuten telnet), käytä toimintoa connect().

#include <sys/types.h>
#include <sys/socket.h>

int  connect(int  sockfd, struct sockaddr *serv_addr, int addrlen );

Luoda käyttäen socket socket(), muuntaa hostname IP-osoite käyttämällä gethostbyname() ja sitten kysymys connect () – kutsu kulkee merkityksellisiä rakenteita, jotka sisältävät IP-osoite ja portti yhteyden.

  struct hostent     *he;
  struct sockaddr_in  server;
  int                 sockfd;

/* resolve localhost to an IP (should be 127.0.0.1) */
  if ((he = gethostbyname("localhost")) == NULL) {
    puts("error resolving hostname..");
    exit(1);
  }

/*
 * copy the network address part of the structure to the 
 * sockaddr_in structure which is passed to connect() 
 */
  memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
  server.sin_family = AF_INET;
  server.sin_port = htons(7000);

/* connect */
  if (connect(sockfd, (struct sockaddr *)&server, sizeof(server))) {
    puts("error connecting..");
    exit(1);
  }

Käyttää connect() … enemmän tulemaan kun/jos saan aikaiseksi.

Leave a Reply