⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clientserver.html

📁 Beej的socket教材
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<HTML><HEAD><TITLE>Client-Server Background</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.70"><LINKREL="HOME"TITLE="Beej's Guide to Network Programming"HREF="index.html"><LINKREL="PREVIOUS"TITLE="System Calls or Bust"HREF="syscalls.html"><LINKREL="NEXT"TITLE="Slightly Advanced Techniques"HREF="advanced.html"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=utf-8"></HEAD><BODYCLASS="sect1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Beej's Guide to Network Programming</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="syscalls.html">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="advanced.html">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="sect1"><H1CLASS="sect1"><ANAME="clientserver">5. Client-Server Background</A></H1><P>It's a client-server world, baby.  Just about everything on thenetwork deals with client processes talking to server processes andvice-versa.  Take <BCLASS="command">telnet</B>, for instance.  When youconnect to a remote host on port 23 with telnet (the client), a programon that host (called <BCLASS="command">telnetd</B>, the server) springs tolife.  It handles the incoming telnet connection, sets you up with alogin prompt, etc.</P><DIVCLASS="figure"><ANAME="figure2"></A><P><B>Figure 2. Client-Server Interaction.</B></P><DIVCLASS="mediaobject"><P><IMGSRC="cs.gif"ALT="[Client-Server Interaction Diagram]"></IMG></P></DIV></DIV><P>The exchange of information between client and server issummarized in <AHREF="clientserver.html#figure2">Figure 2</A>.</P><P>Note that the client-server pair can speak<TTCLASS="constant">SOCK_STREAM</TT>, <TTCLASS="constant">SOCK_DGRAM</TT>, oranything else (as long as they're speaking the same thing.)  Some goodexamples of client-server pairs are<BCLASS="command">telnet</B>/<BCLASS="command">telnetd</B>,<BCLASS="command">ftp</B>/<BCLASS="command">ftpd</B>, or<BCLASS="command">bootp</B>/<BCLASS="command">bootpd</B>.  Every time you use<BCLASS="command">ftp</B>, there's a remote program,<BCLASS="command">ftpd</B>, that serves you.</P><P>Often, there will only be one server on a machine, and that serverwill handle multiple clients using <TTCLASS="function">fork()</TT>.  Thebasic routine is: server will wait for a connection,<TTCLASS="function">accept()</TT> it, and <TTCLASS="function">fork()</TT> achild process to handle it.  This is what our sample server does in thenext section.</P><DIVCLASS="sect2"><H2CLASS="sect2"><ANAME="simpleserver">5.1. A Simple Stream Server</A></H2><P>All this server does is send the string "<TTCLASS="computeroutput">Hello,World!\n</TT>" out over a stream connection.  All you needto do to test this server is run it in one window, and telnet to it fromanother with:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="screen">&#13;    <TTCLASS="prompt">$</TT> <BCLASS="command">telnet remotehostname 3490</B></PRE></TD></TR></TABLE><P>where <TTCLASS="computeroutput">remotehostname</TT> is the nameof the machine you're running it on.</P><P><AHREF="http://www.ecst.csuchico.edu/~beej/guide/net/examples/server.c"TARGET="_top">The server code</A>: (Note: atrailing backslash on a line means that the line is continued on thenext.)</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="programlisting">&#13;    /*    ** server.c -- a stream socket server demo    */    #include &#60;stdio.h&#62;    #include &#60;stdlib.h&#62;    #include &#60;unistd.h&#62;    #include &#60;errno.h&#62;    #include &#60;string.h&#62;    #include &#60;sys/types.h&#62;    #include &#60;sys/socket.h&#62;    #include &#60;netinet/in.h&#62;    #include &#60;arpa/inet.h&#62;    #include &#60;sys/wait.h&#62;    #include &#60;signal.h&#62;    #define MYPORT 3490    // the port users will be connecting to    #define BACKLOG 10     // how many pending connections queue will hold    void sigchld_handler(int s)    {        while(wait(NULL) &#62; 0);    }    int main(void)    {        int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd        struct sockaddr_in my_addr;    // my address information        struct sockaddr_in their_addr; // connector's address information        int sin_size;        struct sigaction sa;        int yes=1;        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {            perror("socket");            exit(1);        }        if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&#38;yes,sizeof(int)) == -1) {            perror("setsockopt");            exit(1);        }                my_addr.sin_family = AF_INET;         // host byte order        my_addr.sin_port = htons(MYPORT);     // short, network byte order        my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP        memset(&#38;(my_addr.sin_zero), '\0', 8); // zero the rest of the struct        if (bind(sockfd, (struct sockaddr *)&#38;my_addr, sizeof(struct sockaddr))                                                                       == -1) {            perror("bind");            exit(1);        }        if (listen(sockfd, BACKLOG) == -1) {            perror("listen");            exit(1);        }        sa.sa_handler = sigchld_handler; // reap all dead processes        sigemptyset(&#38;sa.sa_mask);        sa.sa_flags = SA_RESTART;        if (sigaction(SIGCHLD, &#38;sa, NULL) == -1) {            perror("sigaction");            exit(1);        }        while(1) {  // main accept() loop            sin_size = sizeof(struct sockaddr_in);            if ((new_fd = accept(sockfd, (struct sockaddr *)&#38;their_addr,                                                           &#38;sin_size)) == -1) {                perror("accept");                continue;            }            printf("server: got connection from %s\n",                                               inet_ntoa(their_addr.sin_addr));            if (!fork()) { // this is the child process                close(sockfd); // child doesn't need the listener                if (send(new_fd, "Hello, world!\n", 14, 0) == -1)                    perror("send");                close(new_fd);                exit(0);            }            close(new_fd);  // parent doesn't need this        }        return 0;    } </PRE></TD></TR></TABLE><P>In case you're curious, I have the code in one big<TTCLASS="function">main()</TT> function for (I feel) syntactic clarity.Feel free to split it into smaller functions if it makes you feelbetter.</P><P>(Also, this whole <TTCLASS="function">sigaction()</TT> thing might benew to you--that's ok.  The code that's there is responsible for reapingzombie processes that appear as the <TTCLASS="function">fork()</TT>ed childprocesses exit.  If you make lots of zombies and don't reap them, yoursystem administrator will become agitated.)</P><P>You can get the data from this server by using the clientlisted in the next section.</P></DIV><DIVCLASS="sect2"><H2CLASS="sect2"><ANAME="simpleclient">5.2. A Simple Stream Client</A></H2><P>This guy's even easier than the server.  All this client does isconnect to the host you specify on the command line, port 3490.  It getsthe string that the server sends.</P><P><AHREF="http://www.ecst.csuchico.edu/~beej/guide/net/examples/client.c"TARGET="_top">The clientsource</A>:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="programlisting">&#13;    /*    ** client.c -- a stream socket client demo    */    #include &#60;stdio.h&#62;    #include &#60;stdlib.h&#62;    #include &#60;unistd.h&#62;    #include &#60;errno.h&#62;    #include &#60;string.h&#62;    #include &#60;netdb.h&#62;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -