linux 代理包裹,Linux C高级编程——网络编程之包裹函数

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

#include

#include

#include

#include

#include

#include

#include

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 8000

int 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:46

int i,n;

/* 服务器端开始建立sockfd描述符 */

sockfd = Socket(AF_INET,SOCK_DGRAM,0);// AF_INET:IPV4;SOCK_STREAM:TCP

/* 服务器端填充 sockaddr结构 */

bzero(&servaddr,sizeof(servaddr));// 初始化,置0

servaddr.sin_family = AF_INET;// Internet

servaddr.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转化为整形ip

servaddr.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

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 8000

int main(int argc,char *argv[])

{

struct sockaddr_in servaddr;

int sockfd,n;

char buf[MAXLINE];

char str[INET_ADDRSTRLEN];//系统定义的宏TCP:16 UDP:46

socklen_t servaddr_len;

/* 服务器端开始建立sockfd描述符 */

sockfd = Socket(AF_INET,SOCK_DGRAM,0);

/* 客户程序填充服务端的资料 */

bzero(&servaddr,sizeof(servaddr));// 初始化,置0

servaddr.sin_family = AF_INET;// IPV4

inet_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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值