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!\n"; 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("\n"); 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。实现如下:

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

猜你喜欢

转载自www.cnblogs.com/ptfe/p/11070920.html