Linux C高级编程——网络编程之包裹函数
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                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 <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 8000 int 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; }總結
以上是生活随笔為你收集整理的Linux C高级编程——网络编程之包裹函数的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: vmwaretools安装
- 下一篇: 自动控制原理9.4---李雅普诺夫稳定性
