zoukankan      html  css  js  c++  java
  • Linux 网络编程详解二(socket创建流程、多进程版)

    netstat -na | grep "8080" --查看TCP/IP协议连接状态
    //socket编程提高版--服务器
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    
    int main(int arg, char *args[])
    {
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1)
        {
            perror("socket() err");
            return -1;
        }
        //地址复用
        int on = 1;
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
        {
            perror("setsockopt() err");
            return -1;
        }
        //
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(8080);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        /*
         * INADDR_ANY表示的是IP地址(0,0,0,0)这样的主机字节序变量
         * 本来主机字节序变量转化成网络字节序变量,需要使用htonl()函数,
         * 但是INADDR_ANY比较特殊,它的所有位都是0,不存在大端字节序或者小端字节序的情况
         * 所以不需要使用htonl()函数
         * */
        //表示绑定任意一个地址(但是不推荐,最好使用本机ip地址)
        //addr.sin_addr.s_addr=INADDR_ANY;
        if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
        {
            perror("bind() err");
            return -1;
        }
        /*
         * 一旦调用listen函数,这个套接字sockfd将变成被动套接字,只能接受连接,不能主动发送连接
         * */
        if (listen(sockfd, SOMAXCONN) == -1)
        {
            perror("bind() err");
            return -1;
        }
        struct sockaddr_in peeraddr;
        socklen_t peerlen = sizeof(peeraddr);
        int conn = accept(sockfd, (struct sockaddr *) &peeraddr, &peerlen);
        if (conn == -1)
        {
            perror("accept() err");
            return -1;
        }
        printf("accept by :%s 
    ", inet_ntoa(peeraddr.sin_addr));
        char recvbuf[1024] = { 0 };
        while (1)
        {
            int rc = read(conn, recvbuf, sizeof(recvbuf));
            if (rc == 0)
            {
                printf("client is closed !
    ");
                break;
            } else if (rc < 0)
            {
                printf("read() failed ! error message:%s
    ", strerror(errno));
                break;
            }
            printf("recv message:%s
    ", recvbuf);
            write(conn, recvbuf, rc);
            memset(recvbuf, 0, sizeof(recvbuf));
        }
        close(conn);
        close(sockfd);
        return 0;
    }
    //socket编程提高版--客户端
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    
    int main(int arg, char *args[])
    {
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1)
        {
            perror("socket() err");
            return -1;
        }
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(8080);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
        {
            perror("socket() err");
            return -1;
        }
        char sendbuf[1024]={0};
        char recvbuf[1024]={0};
        while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
        {
            //send
            write(sockfd,sendbuf,sizeof(sendbuf));
            //recv
            int rc=read(sockfd,recvbuf,sizeof(recvbuf));
            if(rc<0)
            {
                perror("read() error");
                break;
            }else if(rc==0)
            {
                printf("connect is cloesd !
    ");
                break;
            }
            printf("recv message:%s
    ",recvbuf);
            memset(sendbuf,0,sizeof(sendbuf));
            memset(recvbuf,0,sizeof(recvbuf));
        }
        return 0;
    }
    //socket编程提高版--多进程版服务器
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    
    int main(int arg, char *args[])
    {
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1)
        {
            perror("socket() err");
            return -1;
        }
        //地址复用
        int on = 1;
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
        {
            perror("setsockopt() err");
            return -1;
        }
        //
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(8080);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        /*
         * INADDR_ANY表示的是IP地址(0,0,0,0)这样的主机字节序变量
         * 本来主机字节序变量转化成网络字节序变量,需要使用htonl()函数,
         * 但是INADDR_ANY比较特殊,它的所有位都是0,不存在大端字节序或者小端字节序的情况
         * 所以不需要使用htonl()函数
         * */
        //表示绑定任意一个地址(但是不推荐,最好使用本机ip地址)
        //addr.sin_addr.s_addr=INADDR_ANY;
        if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
        {
            perror("bind() err");
            return -1;
        }
        /*
         * 一旦调用listen函数,这个套接字sockfd将变成被动套接字,只能接受连接,不能主动发送连接
         * */
        if (listen(sockfd, SOMAXCONN) == -1)
        {
            perror("bind() err");
            return -1;
        }
        //int conn = 0;
        while (1)
        {
            struct sockaddr_in peeraddr;
            socklen_t peerlen = sizeof(peeraddr);
            int conn = accept(sockfd, (struct sockaddr *) &peeraddr, &peerlen);
            if (conn == -1)
            {
                perror("accept() err");
                return -1;
            }
            printf("accept by :%s 
    ", inet_ntoa(peeraddr.sin_addr));
    
            int pid = fork();
            if (pid == -1)
            {
                perror("fork() err");
                break;
            }
            if (pid == 0)
            {
                char recvbuf[1024] = { 0 };
                while (1)
                {
                    int rc = read(conn, recvbuf, sizeof(recvbuf));
                    if (rc == 0)
                    {
                        printf("client is closed !
    ");
                        break;
                    } else if (rc < 0)
                    {
                        printf("read() failed ! error message:%s
    ",
                                strerror(errno));
                        break;
                    }
                    printf("recv message:%s
    ", recvbuf);
                    write(conn, recvbuf, rc);
                    memset(recvbuf, 0, sizeof(recvbuf));
                }
                close(conn);
                close(sockfd);
                exit(0);
            } else
            {
                close(conn);
            }
        }
        close(sockfd);
        return 0;
    }
  • 相关阅读:
    一起谈.NET技术,抛砖引玉:我看微软.NET各子技术领域之应用前景 狼人:
    一起谈.NET技术,Windows Mobile 6.5的开始菜单 狼人:
    一起谈.NET技术,ASP.NET MVC 验证方式(1) 狼人:
    一起谈.NET技术,强烈推荐体验VisualStudio2010 RC 狼人:
    【华安php入门系列】第1天php的执行方式、执行过程
    败者树Java实现
    Android INSTALL_FAILED_ACWF_INCOMPATIBLE
    《构建高质量的C#代码》,新书上市,欢迎交流!
    oracle中的左右连接
    VS2012 UPDATE 2 发布了离线包
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/6117527.html
Copyright © 2011-2022 走看看