• linux 网络编程-基础篇01


    #Socket简介

    是一个编程接口
    是一种特殊的文件描述符(everything in Unix is a file)
    并不仅限于TCPIP协议
    面向连接(Transmission Control Protocol - TCPIP)
    无连接(User Datagram Protocol-UDP 和 Inter-Network Packet Exchange-IPX)

    #Socket类型
    流式套接字(SOCK_STREAM)
    提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复的发送且
    按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是
    字节流,无长度限制
    数据报套接字(SOCK_DGRAM)
    提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,
    数据可能丢失或重复,顺序发送,可能乱序接收
    原始套接字(SOCK_RAW)
    可以对较低层次协议如IP,ICMP直接访问

    #IP地址
    IP地址是Internet中主机的标识
    Internet中的主机要与别的机器通信必须具有一个IP地址
    IP地址为32位(IPV4)或者128位(IPV6)
    每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包
    选择路由
    表示形式:常用点分形式,如202.38.64.10,最后都会转换为一个32位的无符号
    整数。

    #IP地址的转换
    inet_aton()
    将strptr所指的字符串转换成32位的网络字节序二进制值
    int inet_aton(const char *strptr, struct in_addr *addrptr);
    inet_addr()
    功能同上,返回转换后的地址
    in_addr_t inet_addr(const char *strptr);
    inet_ntoa()
    将32位网络字节序二进制地址转换成点分十进制的字符串。
    char *inet_ntoa(struct in_addr inaddr);

    #端口号
    为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号
    来区分
    TCP端口号与UDP端口号独立(协议不同可以使用同一个端口)
    三无组:协议,IP,端口
    端口号一般由IANA(Internet Assigned Numbers Authority)管理
    众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由
    UNIX系统占用
    已登记端口:1024~49151
    动态或私有端口:49152~65535

    #字节序
    不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):
    小端序(little-endian)-低字节存储在低地址
    将低字节存储在起始地址,称为"Little-Endian"字节序,Intel,AMD等
    采用的是这种方式
    大端序(big-endian)-高序字节存储在低地址
    将高字节存储在起始地址,称为"Big-Endian"字节序,由ARM,Motorola
    等所采用
    网络中传输的数据必须按网络字节序,即大端字节序
    在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当
    应用进程从socket取出整数后,要转化成小端字节序

    #字节序转换函数
    把给定系统所采用的字节序称为主机字节序,为了避免不同类别主机之间在数据
    交换时由于对于字节序的不用而导致的差错,引入了网络字节序
    主机字节序到网络字节序:
    u_long htonl(u_long hostlong);
    u_short htons(u_short short);
    网络字节序到主机字节序
    u_long ntohl(u_long hostlong);
    u_short ntohs(u_short short);

    #网络编程相关API
    int Socket(int domain, int type, int protocol);
    int bind(int Sockfd, struct sockaddr *my_addr, int addrlen);
    int listen(int sockfd, in backlog);
    int accept(int sockfd, struct sockaddr *addr, Socklen_t *addrlen);
    int connect(int sockfd, const struct sockaddr *addr, Socklen_t addrlen);
    ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
            const struct sockaddr *dest_addr, Socklen_t addrlen);
    ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
            struct sockaddr *src_addr, Socklen_t *addrlen);
    int shutdown(int sockfd, int how);

    #command:
    netstat -anpt

    #地址结构的一般用法
    1.定义一个struct sockaddr_in类型的变量并清空
    struct sockaddr_in myaddr;
    memset(&myaddr, 0, sizeof(myaddr));
    2.填充地址信息
    myaddr.sin_family = PF_INET;
    myaddr.sin_port = htons(8888);
    myaddr.sin_addr.s_addr = inet_addr("192.168.1.100");
    3.将该变量强制转换为struct sockaddr类型在函数中使用
    bind(listenfd,(struct sockaddr *)&myaddr, sizeof(myaddr));

    #地址转换函数
    unsigned long inet_addr(const char *address);
    int inet_aton(const char *cp, struct in_addr *inp);
    char *inet_ntoa(struct in_addr in);

    socket流程图:

    附:代码

    client.c

    //int socket(int domain, int type, int protocol);
    //int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    //int listen(int sockfd, int backlog);
    //int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    //uint16_t htons(uint16_t hostshort);
    //int atoi(const char *nptr);
    //in_addr_t inet_addr(const char *cp);
    //void bzero(void *s, size_t n);
    //int listen(int sockfd, int backlog);
    //int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    //int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    
    #include <stdio.h>
    #include <sys/types.h>//socket():bind();listen():accept();listen();accept();connect();
    #include <sys/socket.h>//socket():bind();listen():accept();inet_addr();listen():accept();connect();
    #include <arpa/inet.h>//htons();inet_addr():
    #include <netinet/in.h>//inet_addr():
    #include <strings.h>//bzero();
    #include <stdlib.h>//atoi();exit();
    #include <unistd.h>//close():
    #include <string.h>
    
    #define N 64
    
    int main(int argc, char *argv[])
    {
        if(argc < 3)
        {
            printf("Using: %s ip port
    ",argv[0]);
            exit(-1);
        }
        int sockfd;
        struct sockaddr_in myaddr,peeraddr;
        char buf[N] = {0};
        size_t n;
        socklen_t mylen,peerlen;
        mylen = sizeof(myaddr);
        peerlen = sizeof(peeraddr);
        /*  creat socket  */
        if(-1 == (sockfd = socket(AF_INET,SOCK_DGRAM,0)))
        {
            perror("socket");
            exit(-1);
        }
        /* bind initialization */
        bzero(&myaddr,sizeof(myaddr));
        myaddr.sin_family = AF_INET;
        myaddr.sin_port = htons(atoi(argv[2])+1);
        myaddr.sin_addr.s_addr = inet_addr(argv[1]);
        /*      bind      */
        if(-1 == bind(sockfd, (struct sockaddr *)&myaddr, mylen))
        {
            perror("bind");
            exit(-1);
        }
        /*    connect    */
        bzero(&peeraddr, sizeof(peeraddr));
        peeraddr.sin_family = AF_INET;
        peeraddr.sin_port = htons(atoi(argv[2]));
        peeraddr.sin_addr.s_addr = inet_addr(argv[1]);
        //connect(sockfd,(struct sockaddr *)&peeraddr, peerlen);
        while(1){
        fgets(buf, N, stdin);
        printf("buf:%s",buf);
        if(-1 == (n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&peeraddr, peerlen)))
        {
            perror("sendto");
            exit(-1);
        }
        if(strncmp(buf, "quit", 4) == 0)
                break;
        printf("n = %d
    ",n);
        }
        close(sockfd);
        exit(0);
    }

    server.c

    #include <stdio.h>
    #include <sys/types.h>//socket():bind();listen():accept();listen();accept();connect();
    #include <sys/socket.h>//socket():bind();listen():accept();inet_addr();listen():accept();connect();
    #include <arpa/inet.h>//htons();inet_addr():
    #include <netinet/in.h>//inet_addr():
    #include <strings.h>//bzero();
    #include <stdlib.h>//atoi();exit();
    #include <unistd.h>//close():
    #include <string.h>
    
    #define N 64
    
    typedef struct sockaddr SA;
    
    int main(int argc, char *argv[])
    {
        if(argc < 3)
        {
            printf("Using: %s ip port
    ",argv[0]);
            exit(-1);
        }
    
        int listenfd, connfd;
        struct sockaddr_in myaddr, peeraddr;
        char buf[N] = {0};
        size_t n;
        socklen_t mylen, peerlen;
        mylen = sizeof(myaddr);
        peerlen = sizeof(peeraddr);
        /*    create    socket    */
        if ((listenfd = (socket(PF_INET, SOCK_DGRAM, 0))) < 0)
        {
            perror("socket");
            exit(-1);
        }
        /*    bind initialization    */
        bzero(&myaddr, mylen);
        myaddr.sin_family = PF_INET;
        myaddr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1], &myaddr.sin_addr);
        
        if(bind(listenfd,(SA *)&myaddr, sizeof(myaddr)) < 0)
        {
            perror("bind");
            exit(-1);
        }
        /*    listen        */
        listen(listenfd, 5);
        /*    accept        */
        if(-1 == (connfd = accept(listenfd, (SA *)&peeraddr, &peerlen)))
        {
            perror("accept");
            exit(-1);
        }
        printf("connect from %s: %d
    ",inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));
        /*    recv-send    */
        while(1){
        n = recv(connfd, buf, N, 0);
        buf[n] = 0;
        printf("n = %d---%s
    ",n,buf);
        if(0 == strncmp(buf,"quit",4))
        break;
        send(connfd, buf, strlen(buf), 0);
        }
        close(connfd);
        close(listenfd);
        exit(0);
    }

    原文链接:http://www.cnblogs.com/lr-ting/archive/2012/08/24/2652482.html

    ----

  • 相关阅读:
    05-删除提示
    04-setTimeout
    03-页面加载事件
    02-对话框
    01-window
    18-选择水果
    17-元素操作的方法
    13-动态创建表格
    【数据库】SQL必知必会复习
    【数据库】JDBC课设(2)addbatch批处理SQL语句
  • 原文地址:https://www.cnblogs.com/Ph-one/p/6362469.html
Copyright © 2020-2023  润新知