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

    TCP和UDP
    TCP是 有连接协议(基于连接的协议),想要数据交互必须保持连接,会给服务器带来很大的压力。好处就是 可以重发一切错误数据,因此TCP的数据一定是正确和完整的。
    UDP是 无连接协议,平时不保持任何的连接,服务器压力较小。缺点就是不会主动重发错误数据,因此有可能丢失数据。UDP也可以用connect()进行连接。
    UDP编程
    UDP编程:(socket(SOCK_DGRAM)就是UDP)
    编程步骤:
    1 创建socket(),type必须 SOCK_DGRAM
    2 准备通信地址
    3 如果Server,绑定bind,客户端什么都不用做。
    4 使用 sendto()和recvfrom() 交互数据。
    5 关闭socket。 close()
    注:如果不想 拿发送方的通信地址,read()也可以接收。
    int sendto(int sockfd,void* buf,size_t len,int flags,struct sockaddr* addr,socklen_t size)
    前3个参数与write()一样,flags置0,后两个参数存储接收方的通信地址和地址长度。
    成功返回 发送的字节数,失败 返回 -1.
    ssize_t recvfrom(int sockfd,void* buf,
    size_t len,int flags,struct sockaddr* addr,socklen_t* size)
    前3个参数与read()一样,flags置0,后两个参数存发送方的通信地址和地址长度指针。
    size 是 一个传入传出参数。
    返回实际接收到的字节数,失败 -1.


    例子:
    例子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.182.2");
    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));
    struct sockaddr_in from;
    socklen_t length = sizeof(from);
    int len = recvfrom(sockfd,buf,sizeof(buf),0,
    (struct sockaddr*)&from,&length);
    printf("读到了%d字节,内容:%s ",len,buf);
    sendto(sockfd,"welcome",7,0,
    (struct sockaddr*)&from,sizeof(from));
    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.182.2");
    int res = sendto(sockfd,"hello",5,0,
    (struct sockaddr*)&addr,sizeof(addr));
    //write(sockfd,"hello",5);//无连接也能发才是UDP
    printf("发送了%d字节 ",res);
    char buf[100] = {};
    read(sockfd,buf,sizeof(buf));
    printf("buf=%s ",buf);
    close(sockfd);
    }

    实例:
    用UDP实现一个时间服务器。时间服务器就是取自己的系统时间,返回给客户端。
    客户端先发请求(比如hello),服务器端返回当前系统时间,客户端再显示(年月日小时分秒格式)。
    注:服务器端 要是一个 死循环,用信号退出
    转换日期格式用:
    秒差 time_t 函数time()获取
    年月日小时分秒格式的时间 - struct tm
    转换函数 - localtime()
    例子:
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<signal.h>
    #include<string.h>
    #include<time.h>

    int sockfd;
    void fa(int signo)
    {
    close(sockfd);
    printf("time server is close! ");
    exit(0);
    }
    int main()
    {
    signal(SIGINT,fa);
    printf("按 CTIL+C 退出服务器! ");
    sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd == -1)
    {
    perror("socket"),exit(-1);
    }
    struct scokaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port= htons(2222);
    addr.sin_addr.s_addr=INADDR_ANY;//INADDR_ANY 是跟本机交互的宏,如果跟其他机器交互,用inet_addr
    int res = bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
    if(res == -1)
    {
    perror("bind"),exit(-1);
    }
    printf("bind ok ");

    while(1)
    {
    char buf[100]={};
    struct sockaddr_in fmaddr;
    socklen_t len = sizeof(fmaddr);
    recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&fmaddr,&len);
    printf("客户端%s发送了请求 ",inet_ntoa(from.sin_addr));
    time_t cur_time = time(0);
    struct tm* cur = localtime(&cur_time);
    sprintf(buf,"%4d-%02d-%02d %02d:%02d:%02d",
    cur->tm_year+1900,
    cur->tm_mon+1,
    cur->tm_mday,
    cur->tm_hour,
    cur->tm_min,
    cur->tm_sec);
    sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&fmaddr,sizeof(fmaddr));
    }

    }
    例子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.182.2");
    int res = sendto(sockfd,"hello",5,0,
    (struct sockaddr*)&addr,sizeof(addr));
    //write(sockfd,"hello",5);//无连接也能发才是UDP
    printf("发送了%d字节 ",res);
    char buf[100] = {};
    read(sockfd,buf,sizeof(buf));
    printf("buf=%s ",buf);
    close(sockfd);
    }

  • 相关阅读:
    Mac OS X 10.9 Mavericks 无法启动 WebStorm(PhpStorm)
    JavaScript怎么上传图片
    lazyload support for Zepto.js
    JavaScript的函数
    配置SQLServer(2)——32位和64位系统中的内存配置
    配置SQLServer(1)——为SQLServer配置更多的处理器
    学习使用Word2013向博客园发布随笔
    Kernel与用户进程通信
    IPv6 Ready Logo测试环境搭建
    前端必备的切图技巧
  • 原文地址:https://www.cnblogs.com/aiyq195/p/6433428.html
Copyright © 2011-2022 走看看