• Linux-网络编程-UDP网络编程(day13续2)


     一、基于TCP的网络编程(续day12)

    二、并发服务器

    三、基于UDP的网络编程


    三、基于UDP的网络编程

    1、基于UDP网络编程基础

    (1)报头格式

    头部为8个字节

    (2)编程模型

    或者

     (3)相关函数

    sendto(2)

    #include<sys/types.h>

    #include<sys/socket.h>

    int sendto (int sockfd, const void *buf, size_t len,  int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

    功能:

      在socket上发送一个消息

    参数:

      sockfd:socket(2)的返回值

      buf:指定了消息的存放地址

      len:指定发送消息的长度

      flags:一般为0

      dest_addr:目标地址

      addrlen:目标地址长度

    返回值:

      成功:发送的字节数

      错误:-1,errno被设置

    recvfrom(2)

    #include<sys/types.h>

    #include<sys/socket.h>

    ssize_t recvfrom(int sockfd,void *buf,size_t len,int flags,struct sockaddr *src_addr,socklen_t *addrlen);

    功能:

      从socket接收消息

    参数:

      sockfd:socket(2)的返回值

      buf:指定接收消息的空间

      len:接收消息的长度

      flags:一般为0

      src_addr:保存发送方的地址,如果被指定为NULL,那么addrlen也被是空

      addrlen:值-结果参数,src_addr地址空间的长度

    返回值:

      成功:接收到的字节数

      错误:-1

      发送方正常关闭:0

    2、基于UDP的客户端编程

     (1)创建通讯描述符

      socket(AF_INET,SOCK_DGRAM,0);

    (2)使用通讯描述符向服务器发送数据

      sendto(2)

    (3)等待服务器响应

      recvfrom(2)

    (4)关闭通讯描述符

      close(s_fd);

    3、基于UDP的服务器编程

    (1)创建通讯描述符

      socket(AF_INET,SOCK_DGRAM,0);

    (2)将通讯描述符和服务器的地址空间绑定

      bind(s_fd,(struct sockaddr *)&server,sizeof(server));

    (3)recvfrom等待客户端数据的到来

      recvfrom(2)

    (4)处理客户端数据

    (5)回应客户端消息

    ...

    服务器代码 
    1 #include<stdio.h> 2 #include<sys/socket.h> 3 #include<syspes.h> 4 #include<netinet/in.h> 5 #include<unistd.h> 6 #include<arpa/inet.h> 7 #include<ctype.h> 8 9 typedef struct sockaddr_in SA4; 10 typedef struct sockaddr SA; 11 int main(void){ 12 int s_fd; 13 //创建通讯描述符 14 SA4 server,client; 15 char buf[128]; 16 s_fd=socket(AF_INET,SOCK_DGRAM,0); 17 if(s_fd==-1){ 18 perror("socket"); 19 return 1; 20 } 21 //初始化server的地址空间 22 server.sin_family=AF_INET; 23 server.sin_port=htons(7776); 24 server.sin_addr.s_addr=htonl(INADDR_ANY); 25 //绑定 26 int b=bind(s_fd,(SA *)&server,sizeof(server)); 27 if(b==-1){ 28 perror("bind"); 29 return 2; 30 } 31 int clilen=sizeof(client);//值结果参数没有必要> 赋值吧 32 //等待客户端的请求到来 33 int r; 34 while((r=recvfrom(s_fd,buf,128,0,(SA *)&client, &clilen))>0){ 35 for(int i=0;i<r;i++){ 36 buf[i]=toupper(buf[i]); 37 38 } 39 sendto(s_fd,buf,r,0,(SA *)&client,sizeof(cl ient)); 40 } 41 42 close(s_fd); 43 return 0; 44 } 客户端代码  1 #include<stdio.h> 2 #include<unistd.h> 3 #include<syspes.h> 4 #include<sys/socket.h> 5 #include<string.h> 6 #include<netinet/in.h> 7 #include<arpa/inet.h> 8 9 typedef struct sockaddr SA; 10 typedef struct sockaddr_in SA4; 11 int main(int argc,char *argv[]){ 12 char buf[]="this is a test! "; 13 char rbuf[128]; 14 //创建通讯描述符 15 int s_fd; 16 SA4 server; 17 server.sin_family=AF_INET; 18 server.sin_port=htons(7776); 19 inet_pton(AF_INET,argv[1],&server.sin_addr); 20 s_fd=socket(AF_INET,SOCK_DGRAM,0); 21 if(s_fd==-1){ 22 perror("socket"); 23 return 1; 24 } 25 //向服务器发送消息 26 sendto(s_fd,buf,strlen(buf+1),0,(SA *)&server,s izeof(server)); 27 //从服务器获取相应消息 28 int r; 29 r=recvfrom(s_fd,rbuf,128,0,NULL,NULL); 30 write(1,rbuf,r); 31 printf(" "); 32 close(s_fd); 33 34 return 0; 35 }

    作业:

    客户端给服务器发送一个文件名字。服务器收到文件名字之后,在指定的路径之下查找文件是否存在,如果不存在,服务器给客户端发送404,客户端收到404则提示找不到此文件;如果此文件存在,则向客户端发送200,客户端收到200之后,创建这个文件,然后将这个文件的内容下载到客户端中。

    1、前言

    工作中涉及到文件系统,有时候需要判断文件和目录是否存在。我结合APUE第四章文件和目录,总结一下如何正确判断文件和目录是否存在,方便以后查询。

    2、stat系列函数

    stat函数用来返回与文件有关的结构信息。stat系列函数有三种情况,分别对应文件名称、文件描述符和符号链接文件。stat结构描述了文件的属性,主要包括文件的类型、文件大小等等。详细stat结构如下所示:

    struct stat {
      mode_t  st_mode;  // file type & mode(permissions)
      ino_t   st_ino;   // i-node number(serial number)
      dev_t   st_dev;   // device number(filesystem)
      dev_t   st_rdev;  // device number for specials files
      nlink_t  st_nlink;  // number of links
      uid_t   st_uid;   // user ID of owner
      gid_t   st_gid;   // group ID of owner
      off_t   st_size;  // size in bytes, for regular files
      time_t  st_atime;  // time of last access
      time_t  st_mtime;  // time of last modification
      time_t  st_ctime;  // time of last file status change
      long   st_blksize; // best I/O block size
      long   st_blocks; // number of 512-byte blocks allocated
    };

    我们可以通过stat获取文件的类型和文件大小等信息。文件类型有:普通文件、目录文件、块特殊文件、字符特殊文件、FIFO、套接字和符号链接。要想通过stat系列函数来判断文件或者目录是否存在,当执行stat函数,如果文件存在时,还需进一步判断该文件是普通文件还是目录文件。

    stat系列函数错误返回-1,错误码存在errno中,errno取值如下:

     
     
    1、ENOENT 参数file_name 指定的文件不存在
    2、ENOTDIR 路径中的目录存在但却非真正的目录
    3、ELOOP 欲打开的文件有过多符号连接问题, 上限为16 符号连接4、EFAULT 参数buf 为无效指针, 指向无法存在的内存空间
    5、EACCESS 存取文件时被拒绝
    6、ENOMEM 核心内存不足
    7、ENAMETOOLONG 参数file_name 的路径名称太长

    3、access函数

    access函数按照实际用户ID和实际组进行访问权限测试。函数原型为:

    #include <unistd.h>
    int access(const char *pathname, int mode);

    mode取值:

    F_OK   测试文件是否存在

    R_OK  测试读权限

    W_OK 测试写权限

    X_OK 测试执行权限

    正确判断一个文件是否存在是用access函数,实现如下所示:

    4、oepndir函数

    opendir函数用来打开文件目录,成功返回指针,出错返回NULL。实现如下:

     (文件查找部分来自脚本之家)

  • 相关阅读:
    关于gis未来的发展
    javascript中replace(regExp, function)用法
    万恶的IE之动态添加DOM节点触发window.resize事件
    jquery气泡提示效果
    万恶的IE之鬼影重重
    flash LocalConnection Error #2044: 未处理的 AsyncErrorEvent:
    去掉if/else
    JSTL分页
    jquery实现搜索框类似提示功能(改进)
    C# 操作IIS
  • 原文地址:https://www.cnblogs.com/ptfe/p/11070920.html
Copyright © 2020-2023  润新知