zoukankan      html  css  js  c++  java
  • 套接口socket编程(Client/Server编程实例)

    基本概念                                                                                                                                         

    套接口也就是网络中的ID。网络通信,归根到底还是进程间通信(不同计算机上的进程间的通信)。在网络中,每一个节点(计算机或路由器)都有一个网络地址,也就是IP地址。

    • IP地址:在网络中唯一标识一台主机,32
    • 端口号:在主机中唯一标识一个进程,16
    • IP+port:在网络环境中唯一标识一个进程(socket)

          socket也称套接字,是linux文件的一种类型(伪文件:不占存储空间的文件。linux 有7中文件, 1.普通文件  2.目录(d)3.字符设备文件(c) 4.块设备文件(b) 5.套接口文件(s)[如我们开启MySQL服务后,在/var/lib/mysql/下生成的mysql.sock文件,关闭MySQL服务后,这个文件就消失了],6.管道(p):有两端,读端 r:流出 fd[0]     写段w:流入 fd[1]         7.符号链接文件(l)[有点儿像WIN下的快捷方式]  其中占存储的有三种:普通,目录,软链接)

           socket成对出现,

           一个文件描述符指向两个缓冲区,一个读一个写。

    预备知识                                                                                                                                          、

    网路字节序:

           TCP/IP规定,网路数据流应采用大端字节序,即低地址高字节。(大端:低地址--高位   高地址--地位    小端:低--低 高--高,即端口号和IP地址都是以网路字节序存储的,网络字节序使用的是大端模式。称给某个系统所采用的字节序为主机字节序,它可能是小端模式也可能是大端模式。

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

    #include<arpa/inet.h>
    uint32_t  htoal(uint32_t hostlong);
    uint16_t  htons(uint16_t hostshort);
    //返回的是网络字节序
    uint32_t ntoh1(uint32_t netlong);
    uint16_t ntohs(uint16_t netshort);
    //返回的主机字节序
    //h表示host,to,n代表network,s代表short,l表示long
    //端口16位 ,ip 32位

     套接口的数据结构                                                                                                                                

          在Linux中,每一种协议都有自己的网络地址数据结构,以sockaddr_开头,如IPV4对应的是sockaddr_in.

               //man 7 ip 查看
    
               struct sockaddr_in {
                   sa_family_t    sin_family; /* address family: AF_INET */
                /*套接口结构地址族,如IPV4为AF_INET*/
                   in_port_t      sin_port;   /* port in network byte order */
                /*16位TCP或UDP端口号,网络字节顺序*/
                   struct in_addr sin_addr;   /* internet address */
               };
    
               /* Internet address. */
               struct in_addr {
                   uint32_t       s_addr;     /* address in network byte order */
               };

    C/S编程                                                                                                                                                  

    服务器是指在网络上提供服务的应用程序,客户机是指用户为了得到某种服务所需要 运行的应用程序,即申请服务的程序。一个服务器程序可以同时接收多个客户机的请求。

     

    server.c:
    socket() 建立套接字
    bind()  绑定IP 端口号(struct sockaddr_in addr 初始化)
    listen() 指定最大同时发起连接数
    accept()  阻塞等待客户端发起连接
    read()
    小--大
    write 给客户端
    close();
    client.c:
    socket();
    bind();可以依赖“隐式绑定”,即写不写都行
    connect();发起连接
    write();
    read();
    close();
     1 #include<stdio.h>
     2 #include<unistd.h>
     3 #include<sys/socket.h>
     4 #include<stdlib.h>
     5 #include<arpa/inet.h>
     6 #include<ctype.h>
     7 #include<strings.h>
     8 #define SERV_PORT 6666 //端口号
     9 int main(void)
    10 {
    11    int lfd,cfd;//定义套接口描述符
    12    struct sockaddr_in serv_addr;//定义服务器IPV4套接口地址数据结构serv_addr
    13    struct sockaddr_in clie_addr;//d定义客户端client
    14    socklen_t clie_addr_len;
    15    char buf[BUFSIZ],clie_IP[BUFSIZ];//用BUFSIZ就不需要自己定义宏了
    16    int i,n;
    17    lfd=socket(AF_INET,SOCK_STREAM,0);//AF_INET:IPV4 AF_INET6:IPV6
    18    bzero(&serv_addr,sizeof(serv_addr));//清0,memset清任何数 
    19    serv_addr.sin_family=AF_INET;//设置addr的成员信息
    20    serv_addr.sin_port=htons(SERV_PORT);//本地字节序转换为网络字节序
    21    serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);//IP地址设为本地IP INADDR_ANY本地任意IP
    22 
    23    bind(lfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));//绑定端口
    24 
    25    listen(lfd,128);//最多可以接受128个客户端的请求,监听ifd描述符
    26 
    27    clie_addr_len=sizeof(clie_addr);
    28    cfd=accept(lfd,(struct sockaddr *)&clie_addr,&clie_addr_len);//bind accept connect 需要强转
    29    printf("client IP:%s,client port:%d
    ",inet_ntop(AF_INET,&clie_addr.sin_addr,clie_IP,sizeof(clie_IP)),ntohs(clie_addr.sin_port));
    30    while(1){
    31    n= read(cfd,buf,sizeof(buf));
    32    for(i=0;i<n;i++)
    33    {
    34      buf[i]=toupper(buf[i]);//下写转换为大写
    35    }
    36    write(cfd,buf,n);
    37    }
    38    close(lfd);
    39    close(cfd);
    40 
    41    return 0;
    42 
    43 }
    server.c
     1 #include<stdio.h>
     2 #include<unistd.h>
     3 #include<sys/socket.h>
     4 #include<stdlib.h>
     5 #include<arpa/inet.h>
     6 #include<ctype.h>
     7 #include<string.h>
     8 #define SERV_PORT 6666
     9 #define SERV_IP "127.0.0.1 "
    10 int main(void)
    11 {
    12     int cfd;
    13     int n;
    14     char buf[BUFSIZ];
    15     struct sockaddr_in serv_addr;
    16    // socklen_t serv_addr_len;
    17     cfd = socket(AF_INET,SOCK_STREAM,0);
    18     memset(&serv_addr,0,sizeof(serv_addr));
    19     serv_addr.sin_family=AF_INET;//设置addr的成员信息
    20     serv_addr.sin_port=htons(SERV_PORT);//本地字节序转换为网络字节序
    21     inet_pton(AF_INET,SERV_IP,&serv_addr.sin_addr.s_addr);
    22  //    serv_addr.sin_addr=*((struct in_addr *)host->haddr);
    23     connect(cfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));//客户端程序发起连接请求
    24    while(1)
    25    {
    26    fgets(buf,sizeof(buf),stdin);//hello world ----fgets---"hello world
    "从键盘写 
    27    write(cfd,buf,strlen(buf));
    28    n=read(cfd,buf,sizeof(buf));
    29    write(STDOUT_FILENO,buf,n);
    30    }
    31    close(cfd);
    32    return 0;
    33 }
    client.c

  • 相关阅读:
    mysql复制那点事
    全排列问题
    56. Merge Interval
    2. Add Two Numbers
    20. Valid Parentheses
    121. Best Time to Buy and Sell Stock
    120. Triangle
    96. Unique Binary Search Trees
    91. Decode Ways
    72. Edit Distance
  • 原文地址:https://www.cnblogs.com/wy9264/p/10478353.html
Copyright © 2011-2022 走看看