首页 > 代码库 > Linux_C socket 数据报之client, server.c

Linux_C socket 数据报之client, server.c

dgrecv.c

 1 /**************************************************************** 2  * dgrecv.c - datagram receiver 3  *              usage: dgrecv portnum 4  *             action: listens at the specfied port and reports messages 5  */ 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <sys/types.h> 9 #include <sys/socket.h>10 #include <netinet/in.h>11 #include <netdb.h>12 #include <string.h>13 #include <arpa/inet.h>14 #include <unistd.h>15 16 #define oops(m,x) {perror(m); exit(x);}17 18 int make_dgram_server_socket(int);19 int get_internet_address(char* , int , int *, struct sockaddr_in *);20 void say_who_called(struct sockaddr_in* );21 22 int main(int argc, char* argv[]) {23   int port;24   int sock;25   char buf[BUFSIZ];26   size_t msglen;27   struct sockaddr_in saddr;28   socklen_t saddrlen;29   30   if(argc==1 || (port=atoi(argv[1]))<=0){31     fprintf(stderr, "usage :dgrecv portnumber\n");32     exit(1);33   }34   35   /*get a socket and assign it a port number*/36   if((sock=make_dgram_server_socket(port))==-1)37     oops("cannot make server", 2);38   39   /*receive messages on that socket*/40   saddrlen=sizeof(saddr);41   while((msglen=recvfrom(sock ,buf, BUFSIZ, 0, &saddr, &saddrlen))>0) {42     buf[msglen]=\0;43     printf("dgrecv: got a message: %s\n", buf);44     say_who_called(&saddr);45   }46   return 0;47 }48 49 //return the sock_id50 int make_dgram_server_socket(int port){51   struct sockaddr_in saddr;52   struct hostent *hp;53   char hostname[BUFSIZ];54   int sock;55   56   sock=socket(PF_INET, SOCK_DGRAM, 0);57   if(sock==-1)58     return -1;59   gethostname(hostname, BUFSIZ);60   hp=gethostbyname(hostname);61   bzero((void*)&saddr, sizeof(saddr));62   bcopy(hp->h_addr, (struct sockaddr*)&saddr.sin_addr, hp->h_length);63   saddr.sin_family=AF_INET;64   saddr.sin_port=htons(port);65   if(bind(sock, (struct sockaddr*)&saddr, sizeof(saddr))!=0)66     return -1;67   return sock;68 }69 70 int get_internet_address(char* host, int len, int *portp, struct sockaddr_in* addrp) {71   /*72    * extracts host and port from an internet socket address73    * *addrp->(host, port)74    */75   strncpy(host, inet_ntoa(addrp->sin_addr), len);76   *portp=ntohs(addrp->sin_port);77   return 0;78 }79 80 void say_who_called(struct sockaddr_in *addrp) {81   char host[BUFSIZ];82   int port;83   84   get_internet_address(host, BUFSIZ, &port, addrp);85   printf("from: %s: %d\n", host, port);86 }

dgsend.c

 1 /*********************************************************************** 2  * dgsend.c - datagram sender 3  *            usage: dgsend hostname portnumber "message" 4  *            action: sends message to hostname : portnumber 5  */ 6  7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <sys/types.h>10 #include <sys/socket.h>11 #include <netinet/in.h>12 #include <netdb.h>13 14 #define oops(m, x) {perror(m); exit(x);}15 16 int main(int argc, char* argv[]) {17   char *message;18   int cli_sock;19   struct sockaddr_in saddr;20   struct hostent *hp;21 22   if(argc!=4){23     printf("please cin hostname portnumber and message ./n");24     exit(-1);25   }26   cli_sock=socket(AF_INET, SOCK_DGRAM, 0);27   if(cli_sock==-1) 28     oops("cannot make socket", 2);29   30   message=argv[3];31 32   /*make internet address*/33   bzero((void*)&saddr, sizeof(saddr));34   hp=gethostbyname(argv[1]);35   bcopy(hp->h_addr, (struct sockaddr*)&saddr.sin_addr, hp->h_length);36   saddr.sin_family=AF_INET;37   saddr.sin_port=htons(atoi(argv[2]));38   39   if(sendto(cli_sock, message, strlen(message), 0, &saddr, sizeof(saddr))==-1)40     oops("sendto failed", 3);41   return 0;42 }

其中,注意

为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

#include <arpa/inet.h>
uint32_t
uint16_t
uint32_t
uint16_t
htonl(uint32_t
htons(uint16_t
ntohl(uint32_t
ntohs(uint16_t
hostlong);
hostshort);
netlong);
netshort);
这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。例
如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。如果
主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些
函数不做转换,将参数原封不动地返回。

Linux_C socket 数据报之client, server.c