zoukankan      html  css  js  c++  java
  • 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
    ");
    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]='';
    43     printf("dgrecv: got a message: %s
    ", buf);
    44     say_who_called(&saddr);
    45   }
    46   return 0;
    47 }
    48 
    49 //return the sock_id
    50 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 address
    73    * *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
    ", 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地址转换后准备发送。如果
    主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些
    函数不做转换,将参数原封不动地返回。

  • 相关阅读:
    使用visio 2007对现有的数据库进行反向工程
    GOOGLE地图坐标拾取方法、GOOGLE地图获取坐标方法
    Visio 2007中进行数据库建模时如何显示字段类型以及概念名称
    WCF把书读薄(4)——事务编程与可靠会话
    WCF把书读薄(3)——数据契约、消息契约与错误契约
    WCF把书读薄(2)——消息交换、服务实例、会话与并发
    Backbone.js developer 武汉 年薪8w-10w
    Java面试
    从pb文件中恢复计算图并在tensorboard中展示
    Ubuntu下解决u盘变成只读模式
  • 原文地址:https://www.cnblogs.com/wizzhangquan/p/4104418.html
Copyright © 2011-2022 走看看