📄 clientserver.html
字号:
#include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define PORT 3490 // the port client will be connecting to #define MAXDATASIZE 100 // max number of bytes we can get at once int main(int argc, char *argv[]) { int sockfd, numbytes; char buf[MAXDATASIZE]; struct hostent *he; struct sockaddr_in their_addr; // connector's address information if (argc != 2) { fprintf(stderr,"usage: client hostname\n"); exit(1); } if ((he=gethostbyname(argv[1])) == NULL) { // get the host info perror("gethostbyname"); exit(1); } if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(PORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror("recv"); exit(1); } buf[numbytes] = '\0'; printf("Received: %s",buf); close(sockfd); return 0; } </PRE></TD></TR></TABLE><P>Notice that if you don't run the server before you run the client,<TTCLASS="function">connect()</TT> returns "Connection refused". Veryuseful.</P></DIV><DIVCLASS="sect2"><H2CLASS="sect2"><ANAME="datagram">5.3. Datagram Sockets</A></H2><P>I really don't have that much to talk about here, so I'll justpresent a couple of sample programs: <TTCLASS="filename">talker.c</TT> and<TTCLASS="filename">listener.c</TT>.</P><P><BCLASS="command">listener</B> sits on a machine waiting for anincoming packet on port 4950. <BCLASS="command">talker</B> sends a packetto that port, on the specified machine, that contains whatever the userenters on the command line.</P><P>Here is the <AHREF="http://www.ecst.csuchico.edu/~beej/guide/net/examples/listener.c"TARGET="_top">source for<TTCLASS="filename">listener.c</TT></A>:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="programlisting"> /* ** listener.c -- a datagram sockets "server" demo */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define MYPORT 4950 // the port users will be connecting to #define MAXBUFLEN 100 int main(void) { int sockfd; struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information int addr_len, numbytes; char buf[MAXBUFLEN]; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); 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(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } addr_len = sizeof(struct sockaddr); if ((numbytes=recvfrom(sockfd,buf, MAXBUFLEN-1, 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); } printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr)); printf("packet is %d bytes long\n",numbytes); buf[numbytes] = '\0'; printf("packet contains \"%s\"\n",buf); close(sockfd); return 0; } </PRE></TD></TR></TABLE><P>Notice that in our call to <TTCLASS="function">socket()</TT> we'refinally using <TTCLASS="constant">SOCK_DGRAM</TT>. Also, note that there'sno need to <TTCLASS="function">listen()</TT> or<TTCLASS="function">accept()</TT>. This is one of the perks of usingunconnected datagram sockets!</P><P>Next comes the <AHREF="http://www.ecst.csuchico.edu/~beej/guide/net/examples/talker.c"TARGET="_top">source for<TTCLASS="filename">talker.c</TT></A>:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="programlisting"> /* ** talker.c -- a datagram "client" demo */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #define MYPORT 4950 // the port users will be connecting to int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in their_addr; // connector's address information struct hostent *he; int numbytes; if (argc != 3) { fprintf(stderr,"usage: talker hostname message\n"); exit(1); } if ((he=gethostbyname(argv[1])) == NULL) { // get the host info perror("gethostbyname"); exit(1); } if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1); } their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(MYPORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1); } printf("sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr)); close(sockfd); return 0; } </PRE></TD></TR></TABLE><P>And that's all there is to it! Run <BCLASS="command">listener</B> onsome machine, then run <BCLASS="command">talker</B> on another. Watch themcommunicate! Fun G-rated excitement for the entire nuclearfamily!</P><P>Except for one more tiny detail that I've mentioned many times inthe past: connected datagram sockets. I need to talk about this here,since we're in the datagram section of the document. Let's say that<BCLASS="command">talker</B> calls <TTCLASS="function">connect()</TT> andspecifies the <BCLASS="command">listener</B>'s address. From that pointon, <BCLASS="command">talker</B> may only sent to and receive from theaddress specified by <TTCLASS="function">connect()</TT>. For this reason,you don't have to use <TTCLASS="function">sendto()</TT> and<TTCLASS="function">recvfrom()</TT>; you can simply use<TTCLASS="function">send()</TT> and <TTCLASS="function">recv()</TT>.</P></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="syscalls.html">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="advanced.html">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">System Calls or Bust</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"> </TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Slightly Advanced Techniques</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -