Linux C高级编程——网络编程之包裹函数

来源:互联网 发布:智能语音翻译软件 编辑:程序博客网 时间:2024/06/01 09:49

                                    Linux网络编程(六)——包裹函数


                         宗旨:技术的学习是有限的,分享的精神是无限的。


         系统调用不能保证每次都成功,必须进行出错处理。包裹函数就是把一般函数加了出错处理。包裹函数首字母大写。

/*************************************************************************    > File Name: wrap.h    > Author: libang    > Mail: 1838039453@qq.com     > Created Time: 2016年04月06日 星期三 17时23分35秒 ************************************************************************/#ifndef WRAP_H#define WRAP_H#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/socket.h>#include <string.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>void perr_exit(const char *s);int Accept(int fd,struct sockaddr *sa,socklen_t *salenptr);void Bind(int fd,const struct sockaddr* sa,socklen_t salen);void Connect(int fd,const struct sockaddr* sa,socklen_t salen);void Listen(int fd,int backlog);int Socket(int family,int type,int protocol);ssize_t Read(int fd,void *ptr,size_t nbytes);ssize_t Write(int fd,const void *ptr,size_t nbytes);ssize_t Readn(int fd,void *vptr,size_t n);ssize_t Writen(int fd,const void*vptr,size_t n);static ssize_t my_read(int fd,char *ptr);static Readline(int fd,void *vptr,size_t maxlen);void Close(int fd);#endif

/*************************************************************************    > File Name: wrap.c    > Author: libang    > Mail: 1838039453@qq.com    > Created Time: 2016年04月06日 星期三 17时53分25秒 ************************************************************************/#include "wrap.h"void perr_exit(const char *s){  perror(s);  exit(1);}int Accept(int fd, struct sockaddr *sa, socklen_t* salenptr){  int newfd;again:  if((newfd = accept(fd, sa, salenptr)) < 0)  {    if((errno == ECONNABORTED) || (errno == EINTR))    {      goto again;    }    else    {      perr_exit("accept error");    }  }  return newfd;}void Bind(int fd, const struct sockaddr* sa, socklen_t salen){  if(bind(fd, sa, salen) < 0)  {    perr_exit("bind error");  }}void Connect(int fd, const struct sockaddr *sa, socklen_t salen){  if(connect(fd, sa, salen) < 0)  {    perr_exit("connect error");  }}void Listen(int fd, int backlog){  if(listen(fd, backlog) < 0)  {    perr_exit("listen error");  }}int Socket(int family, int type, int protocol){  int socketfd;  if((socketfd = socket(family, type, protocol)) < 0)  {    perr_exit("socket error");  }  return socketfd;}ssize_t Read(int fd, void *ptr, size_t nbytes){  ssize_t n;again:  if((n = read(fd, ptr, nbytes)) == -1)  {    if(errno == EINTR)    {      goto again;    }    else    {      return -1;    }  }  return n;}ssize_t Write(int fd, const void *ptr, size_t nbytes){  ssize_t n;again:  if((n = write(fd, ptr, nbytes)) == -1)  {    if(errno == EINTR)    {      goto again;    }    else    {      return -1;    }  }  return n;}ssize_t Readn(int fd, void *vptr, size_t n){  size_t nleft;  ssize_t nread;  char *ptr;  ptr = vptr;  nleft = n;  while(nleft > 0)  {    if((nread = read(fd, ptr, nleft)) < 0)    {      if(errno == EINTR)      {        nread = 0;      }      else      {        return -1;      }    }    else if(nread == 0)    {      break;    }    nleft -= nread;    ptr += nread;  }  return (n - nleft);}ssize_t Writen(int fd, const void *vptr, size_t n){  size_t nleft;  ssize_t nwritten;  const char* ptr;  ptr = vptr;  nleft = n;  while(nleft > 0)  {    if((nwritten = write(fd, ptr, nleft)) <= 0)    {      if(nwritten < 0 && errno == EINTR)      {        nwritten = 0;      }      else      {        return -1;      }    }    nleft -= nwritten;    ptr += nwritten;  }  return n;}static ssize_t my_read(int fd, char *ptr){  static int read_cnt;  static char *read_ptr;  static char read_buf[100];  if(read_cnt <= 0)  {again:    if((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0)    {      if(errno == EINTR)      {        goto again;      }      else      {        return -1;      }    }    else if(read_cnt == 0)    {      return 0;    }    read_ptr = read_buf;  }  read_cnt--;  *ptr = *read_ptr++;  return 1;}ssize_t Readline(int fd, void *vptr, size_t maxlen){  ssize_t n, rc;  char c, *ptr;  ptr = vptr;  for(n = 1; n < maxlen; n++)  {    if((rc = my_read(fd, &c)) == 1)    {      *ptr++ = c;      if(c == '\n')      {        break;      }    }    else if(rc == 0)    {      *ptr = 0;      return n - 1;    }    else    {      return (n - 1);    }  }  *ptr = 0;  return n;}void Close(int fd){  if(close(fd) == -1)  {    perr_exit("close error");  }}
/*************************************************************************    > File Name: server.c    > Author: libang    > Mail: 1838039453@qq.com     > Created Time: 2016年04月6日 星期日 23时51分26秒 ************************************************************************/#include "wrap.h"#define MAXLINE 80#define SERV_PORT 8000int main(int argc,char *argv[]){struct sockaddr_in servaddr,cliaddr;socklen_t cliaddr_len;int sockfd;char buf[MAXLINE];char str[INET_ADDRSTRLEN];//系统定义的宏TCP:16  UDP:46int i,n;/* 服务器端开始建立sockfd描述符 */ sockfd = Socket(AF_INET,SOCK_DGRAM,0);// AF_INET:IPV4;SOCK_STREAM:TCP/* 服务器端填充 sockaddr结构 */ bzero(&servaddr,sizeof(servaddr));// 初始化,置0servaddr.sin_family = AF_INET;// Internetservaddr.sin_addr.s_addr = htonl(INADDR_ANY);// (将本机器上的long数据转化为网络上的long数据)和任何主机通信  //INADDR_ANY 表示可以接收任意IP地址的数据,即绑定到所有的IP//server_addr.sin_addr.s_addr=inet_addr("192.168.1.1");  //用于绑定到一个固定IP,inet_addr用于把数字加格式的ip转化为整形ipservaddr.sin_port = htons(SERV_PORT);// (将本机器上的short数据转化为网络上的short数据)端口号/* 捆绑sockfd描述符到IP地址 */ Bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));printf("Accept connections ...\n");while(1){cliaddr_len = sizeof(cliaddr);//地址长度n = recvfrom(sockfd,buf,MAXLINE,0,(struct sockaddr *)&cliaddr,&cliaddr_len );//接收客户端信息到buf中if(n == -1)perr_exit("recvfrom error");printf("recvfrom from %s at PORT %d\n",inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),ntohs(cliaddr.sin_port));for(i=0;i<n;i++)buf[i] = toupper(buf[i]);//小写转大写n = sendto(sockfd,buf,n,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));//把buf内容发送sockfd中发给客户端if(n == -1)perr_exit("sendto error");}return 0;}
/*************************************************************************    > File Name: client.c    > Author: libang    > Mail: 1838039453@qq.com     > Created Time: 2016年04月6日 星期一 23时03分44秒 ************************************************************************/#include "wrap.h"#define MAXLINE 80#define SERV_PORT 8000int main(int argc,char *argv[]){struct sockaddr_in servaddr;int sockfd,n;char buf[MAXLINE];char str[INET_ADDRSTRLEN];//系统定义的宏TCP:16  UDP:46socklen_t servaddr_len;/* 服务器端开始建立sockfd描述符 */sockfd = Socket(AF_INET,SOCK_DGRAM,0);/* 客户程序填充服务端的资料 */ bzero(&servaddr,sizeof(servaddr));// 初始化,置0servaddr.sin_family = AF_INET;// IPV4inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);// IP地址servaddr.sin_port = htons(SERV_PORT);// (将本机器上的short数据转化为网络上的short数据)端口号while(fgets(buf,MAXLINE,stdin) != NULL)//从键盘输入内容{/*发送buf到sockfd中*/n = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&servaddr,sizeof(servaddr));if(n == -1)perr_exit("recvfrom error");n = recvfrom(sockfd,buf,MAXLINE,0,NULL,0);if(n == -1)perr_exit("recvfrom error");Write(STDOUT_FILENO,buf,n);//写到标准输出中}Close(sockfd);return 0;}

0 0
原创粉丝点击