zoukankan      html  css  js  c++  java
  • socket-(2)

    网络编程(2)
    网络编程需要使用通信地址 sockaddr_in,其中的端口和IP都要做转换,端口要从本机格式转网络格式,IP要从点分十进制转十六进制。函数:
    htons() - 本机 转 网络
    inet_addr() - 点分十进制 转 十六进制
    ntohs() - 网络 转 本机(从网络取数据到本机)
    inet_ntoa() - 十六进制 转 点分十进制

    例子:简单的例子,就是将socket联通
    例子1:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    int main(){
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd == -1) perror("socket"),exit(-1);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;//网络
    addr.sin_port = htons(2222);//端口需要处理一下
    addr.sin_addr.s_addr = //IP需要转换
    inet_addr("192.168.112.137");
    int res = bind(sockfd,
    (struct sockaddr*)&addr,sizeof(addr));
    if(res == -1) perror("bind"),exit(-1);
    printf("bind ok ");
    char buf[100] = {};
    int len = read(sockfd,buf,sizeof(buf));
    printf("读到了%d字节,内容:%s ",len,buf);
    close(sockfd);
    }

    例子2:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    int main(){
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd == -1) perror("socket"),exit(-1);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;//网络
    addr.sin_port = htons(2222);//服务器的端口
    addr.sin_addr.s_addr = //服务器的IP
    inet_addr("192.168.112.135");
    int res = connect(sockfd,
    (struct sockaddr*)&addr,sizeof(addr));
    if(res == -1) perror("connect"),exit(-1);
    printf("connect ok ");
    write(sockfd,"hello",5);
    close(sockfd);
    }

    aiyq195@aiyq195-virtual-machine:~/桌面/uc/day12/day12$ ./socknetabind ok
    读到了5字节,内容:hello

    aiyq195@aiyq195-virtual-machine:~/桌面/uc/day12/day12$ ./socknetb
    connect ok

    TCP网络编程
    编程步骤:
    一对多(也实现一对一):
    服务器端:
    1 创建socket描述符 socket()
    2 准备通信地址,用sockaddr_in
    3 绑定bind(),开放权限。
    4 监听客户端的连接 listen()
    5 等待客户端的连接 accept(),返回一个新的socket描述符,用于与客户端的交互。
    6 read() write() 读写数据
       7 close()
    客户端的代码步骤不变。
    listen(int sockfd,int backlog)
    参数 sockfd 就是第一步的返回值
    backlog就是当正在处理客户端连接时,有新的客户端连接,会把新的请求放入队列,backlog就是 这个队列的最大长度。而如果处理完毕,从队列中拿出新的请求,队列就会变短。

    int accept(int sockfd,struct sockaddr* addr,socklen_t* len)
    参数 sockfd 就是第一步的返回值
    addr 用于存储 客户端的IP
    len 是传入传出参数,传入addr的大小,传出真实的大小。
    注:使用TCP编程时,socket()中的type必须用:SOCK_STREAM
    accpet()函数会阻塞,直到有客户端连接才能解除。
    信息交互时,服务器和客户端一定要保持读写的一致性。一个读,另外一个必须写。
    例子:
    例子1 tcpserver.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <arpa/inet.h>

    int main(){
    int sockfd = socket(AF_INET,SOCK_STREAM,0);//1创建
    if(sockfd == -1) perror("socket"),exit(-1);
    struct sockaddr_in addr;//2 通信地址
    addr.sin_family = AF_INET;
    addr.sin_port = htons(2222);
    addr.sin_addr.s_addr =
    inet_addr("192.168.112.135");
    int res = bind(sockfd, //3 绑定
    (struct sockaddr*)&addr,sizeof(addr));
    if(res == -1) perror("bind"),exit(-1);
    printf("bind ok ");
    if(listen(sockfd,100) == -1) //4 监听
    perror("listen"),exit(-1);
    struct sockaddr_in from;//5 等待客户端连接
    socklen_t len = sizeof(from);
    int fd = accept(sockfd,(struct sockaddr*)&from,
    &len);
    if(fd == -1) perror("accpet"),exit(-1);
    printf("客户端%s成功连接 ",
    inet_ntoa(from.sin_addr));
    char buf[100] = {};
    read(fd,buf,sizeof(buf));
    printf("buf=%s ",buf);
    write(fd,"welcome",7);
    close(fd);
    close(sockfd);
    }


    例子2: client.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <string.h>

    int main(){
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1) perror("socket"),exit(-1);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;//网络
    addr.sin_port = htons(2222);//服务器的端口
    addr.sin_addr.s_addr = //服务器的IP
    inet_addr("192.168.112.135");
    int res = connect(sockfd,
    (struct sockaddr*)&addr,sizeof(addr));
    if(res == -1) perror("connect"),exit(-1);
    printf("connect ok ");
    char buf[100] = {};
    while(1){
    printf("请输入聊天的内容: ");
    scanf("%s",buf);//加‘’
    //1 break;服务器不知道 客户端退出
    write(sockfd,buf,strlen(buf));
    if(!strcmp(buf,"bye")) break;
    memset(buf,0,sizeof(buf));//清0
    read(sockfd,buf,sizeof(buf));
    printf("buf=%s ",buf);
    memset(buf,0,sizeof(buf));//清0
    }
    close(sockfd);
    }

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <string.h>

    int sockfd;
    void fa(int signo){
    printf("关闭服务器 ");
    close(sockfd);
    exit(0);
    }
    int main(){
    printf("按Ctrl+C退出服务器 ");
    signal(SIGINT,fa);
    sockfd = socket(AF_INET,SOCK_STREAM,0);//1创建
    if(sockfd == -1) perror("socket"),exit(-1);
    struct sockaddr_in addr;//2 通信地址
    addr.sin_family = AF_INET;
    addr.sin_port = htons(2222);
    addr.sin_addr.s_addr =
    inet_addr("192.168.112.135");
    int reuseaddr = 1;//避免重启时 地址被占用 错误
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,
    &reuseaddr,sizeof(reuseaddr));
    int res = bind(sockfd, //3 绑定
    (struct sockaddr*)&addr,sizeof(addr));
    if(res == -1) perror("bind"),exit(-1);
    printf("bind ok ");
    if(listen(sockfd,100) == -1) //4 监听
    perror("listen"),exit(-1);
    while(1){
    struct sockaddr_in from;//5 等待客户端连接
    socklen_t len = sizeof(from);
    int fd = accept(sockfd,(struct sockaddr*)&from,
    &len);
    if(fd == -1) perror("accpet"),exit(-1);
    printf("客户端%s成功连接 ",
    inet_ntoa(from.sin_addr));
    pid_t pid = fork();//accept()会阻塞
    if(pid==0){
    char buf[100] = {};
    while(1){
    int le = read(fd,buf,sizeof(buf));
    if(le<=0) break;
    printf("buf=%s ",buf);
    if(!strcmp(buf,"bye")) break;
    write(fd,buf,le);
    memset(buf,0,sizeof(buf));
    }
    close(fd); exit(0); }
    close(fd);//父进程关闭描述符
    }
    //close(sockfd);//练习:用信号关闭sockfd。
    }

  • 相关阅读:
    android ioctl fuzz,android 本地提权漏洞 android root
    syscall 中断号
    EAT/IAT Hook
    VC中如何获取当前时间(精度达到毫秒级)
    Js表单验证控件-02 Ajax验证
    Js表单验证控件(使用方便,无需编码)-01使用说明
    字符串对比
    KindEditor编辑器For DotNet控件
    模板引擎开发(三)-自定义标签的处理
    Flash AS实现时钟效果(全脚本实现)
  • 原文地址:https://www.cnblogs.com/aiyq195/p/6433419.html
Copyright © 2011-2022 走看看