出错封装函数
/*** client.c ***/ #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include "wrap.h" #define SERV_IP "127.0.0.1" #define SERV_PORT 6666 int main(void) { int sfd, len; struct sockaddr_in serv_addr; char buf[BUFSIZ]; sfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr); serv_addr.sin_port = htons(SERV_PORT); Connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); while (1) { fgets(buf, sizeof(buf), stdin); int r = Write(sfd, buf, strlen(buf)); printf("Write r ======== %d\n", r); len = Read(sfd, buf, sizeof(buf)); printf("Read len ========= %d\n", len); Write(STDOUT_FILENO, buf, len); } Close(sfd); return 0; }
/*** server.c ***/ #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <strings.h> #include <string.h> #include <ctype.h> #include <arpa/inet.h> #include "wrap.h" #define SERV_PORT 6666 int main(void) { int sfd, cfd; int len, i; char buf[BUFSIZ], clie_IP[BUFSIZ]; struct sockaddr_in serv_addr, clie_addr; socklen_t clie_addr_len; sfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_PORT); Bind(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); Listen(sfd, 2); printf("wait for client connect ...\n"); clie_addr_len = sizeof(clie_addr_len); cfd = Accept(sfd, (struct sockaddr *)&clie_addr, &clie_addr_len); printf("cfd = ----%d\n", cfd); printf("client IP: %s port:%d\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)), ntohs(clie_addr.sin_port)); while (1) { len = Read(cfd, buf, sizeof(buf)); Write(STDOUT_FILENO, buf, len); for (i = 0; i < len; i++) buf[i] = toupper(buf[i]); Write(cfd, buf, len); } Close(sfd); Close(cfd); return 0; }
/*** wrap.h ***/ #ifndef __WRAP_H_ #define __WRAP_H_ void perr_exit(const char *s); int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr); int Bind(int fd, const struct sockaddr *sa, socklen_t salen); int Connect(int fd, const struct sockaddr *sa, socklen_t salen); int 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); int Close(int fd); ssize_t Readn(int fd, void *vptr, size_t n); ssize_t Writen(int fd, const void *vptr, size_t n); ssize_t my_read(int fd, char *ptr); ssize_t Readline(int fd, void *vptr, size_t maxlen); #endif
/*** wrap.c ***/ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <sys/socket.h> void perr_exit(const char *s) { perror(s); exit(-1); } int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) { int n; again: if ((n = accept(fd, sa, salenptr)) < 0) { if ((errno == ECONNABORTED) || (errno == EINTR)) goto again; else perr_exit("accept error"); } return n; } int Bind(int fd, const struct sockaddr *sa, socklen_t salen) { int n; if ((n = bind(fd, sa, salen)) < 0) perr_exit("bind error"); return n; } int Connect(int fd, const struct sockaddr *sa, socklen_t salen) { int n; n = connect(fd, sa, salen); if (n < 0) { perr_exit("connect error"); } return n; } int Listen(int fd, int backlog) { int n; if ((n = listen(fd, backlog)) < 0) perr_exit("listen error"); return n; } int Socket(int family, int type, int protocol) { int n; if ((n = socket(family, type, protocol)) < 0) perr_exit("socket error"); return n; } 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; } int Close(int fd) { int n; if ((n = close(fd)) == -1) perr_exit("close error"); return n; } /*参三: 应该读取的字节数*/ //socket 4096 readn(cfd, buf, 4096) nleft = 4096-1500 ssize_t Readn(int fd, void *vptr, size_t n) { size_t nleft; //usigned int 剩余未读取的字节数 ssize_t nread; //int 实际读到的字节数 char *ptr; ptr = vptr; nleft = n; //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; //nleft = 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) { //"hello\n" if (errno == EINTR) goto again; return -1; } else if (read_cnt == 0) return 0; read_ptr = read_buf; } read_cnt--; *ptr = *read_ptr++; return 1; } /*readline --- fgets*/ //传出参数 vptr 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[] = hello\n *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { *ptr = 0; return n-1; } else return -1; } *ptr = 0; return n; }
以下是自己实现有BUG版本
/*** client.c ***/ #include<stdio.h> #include<unistd.h> #include<string.h> #include<string.h> #include<sys/socket.h> #include<arpa/inet.h> #include"wrap.h" #define SERV_IP "127.0.0.1" #define SERV_PORT 6666 int main() { int sfd,len; struct sockaddr_in serv_addr; char buf[BUFSIZ]; sfd = Socket(AF_INET,SOCK_STREAM,0); bzero(&serv_addr,sizeof(serv_addr) ); serv_addr.sin_family = AF_INET; inet_pton(AF_INET,SERV_IP,&serv_addr.sin_addr.s_addr); serv_addr.sin_port = htons(SERV_PORT); Connect(sfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr) ); while(1) { fgets(buf,sizeof(buf),stdin); int r = Write(sfd,buf,strlen(buf)); printf("Write r ========= %d\n",r); len = Read(sfd,buf,sizeof(buf)); printf("Read len ================ %d\n",len); Write(STDOUT_FILENO,buf,len); } Close(sfd); return 0; }
/*** server.c ***/ #include<stdio.h> #include<unistd.h> #include<sys/socket.h> #include<sys/types.h> #include<strings.h> #include<string.h> #include<ctype.h> #include<arpa/inet.h> #include"wrap.h" #define SERV_PORT 6666 int main() { int sfd,cfd; int len,i; char buf[BUFSIZ],clie_IP[BUFSIZ]; struct sockaddr_in serv_addr,clie_addr; socklen_t clie_addr_len; sfd = Socket(AF_INET,SOCK_STREAM,0); bzero(&serv_addr,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_PORT); Bind(sfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); Listen(sfd,2); printf("Wait for client connect ...\n"); clie_addr_len = sizeof(clie_addr_len); cfd = Accept(sfd,(struct sockaddr*)&clie_addr,&clie_addr_len); printf("cfd = ---------%d\n",cfd); printf("client IP:%s port:%d\n", inet_ntop(AF_INET,&clie_addr.sin_addr.s_addr,clie_IP,sizeof(clie_IP)), ntohs(clie_addr.sin_port)); while(1) { len = Read(cfd,buf,sizeof(buf)); Write(STDOUT_FILENO,buf,len); for(i = 0; i < len; i++) { buf[i] = toupper(buf[i]); } Write(cfd,buf,len); } close(sfd); close(cfd); return 0; }
/*** wrap.h ***/ #ifndef __WRAP_H__ #define __WRAP_H__ #include<stdlib.h> #include<stdio.h> #include<unistd.h> #include<errno.h> #include<sys/socket.h> void perr_exit(const char* s); int Accept(int fd,struct sockaddr *sa,socklen_t *salenptr); int Bind(int fd,const struct sockaddr *sa,socklen_t salen); int Connect(int fd,const struct sockaddr *sa,socklen_t salen); int 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); int Close(int fd); ssize_t Readn(int fd,void *vptr,size_t n); ssize_t Writen(int fd,const void *vptr,size_t n); ssize_t my_read(int fd,char *ptr); ssize_t Readline(int fd,void *vptr,size_t maxlen); #endif
/*** wrap.c ***/ #include"wrap.h" void perr_exit(const char* s) { perror(s); exit(-1); } int Accept(int fd,struct sockaddr *sa,socklen_t *salenptr) { int iRet; again: if((iRet == accept(fd,sa,salenptr)) < 0 ) { if( (errno == ECONNABORTED) || (errno == EINTR)) //econnaborted eintr goto again; else perr_exit("accept error"); } return iRet; } int Bind(int fd,const struct sockaddr *sa,socklen_t salen) { int iRet; if((iRet = bind(fd,sa,salen)) < 0) { perr_exit("bind error"); } return iRet; } int Connect(int fd,const struct sockaddr *sa,socklen_t salen) { int iRet; iRet = connect(fd,sa,salen); if(iRet < 0) { perr_exit("connect error"); } return iRet; } int Listen(int fd,int backlog) { int iRet; if((iRet = listen(fd,backlog)) < 0) { perr_exit("listen error"); } return iRet; } int Socket(int family,int type,int protocol) { int iRet; if((iRet = socket(family,type,protocol)) < 0) { perr_exit("socket error"); } return iRet; } ssize_t Read(int fd,void *ptr,size_t nbytes) { ssize_t iRet; again: if((iRet == read(fd,ptr,nbytes)) == -1) { if(errno == EINTR) goto again; else return -1; } return iRet; } ssize_t Write(int fd,const void *ptr,size_t nbytes) { ssize_t iRet; again: if((iRet == write(fd,ptr,nbytes)) == -1) { if(errno == EINTR) goto again; else return -1; } return iRet; } int Close(int fd) { int iRet; if((iRet = close(fd)) == -1 ) { perr_exit("close error"); } return iRet; } ssize_t Readn(int fd,void *vptr,size_t n) { size_t nleft; //unsigned int -- the bytes that no read ssize_t nread; //int the bytes reading factly char *ptr; ptr = vptr; nleft = n; //n -- bytes that no read 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 nwriteten; const char *ptr; ptr = vptr; nleft = n; while(nleft > 0) { if((nwriteten = write(fd,ptr,nleft)) <= 0) { if(nwriteten < 0 && errno == EINTR) { nwriteten = 0; } else { return -1; } nleft -= nwriteten; ptr += nwriteten; } } return n; } 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; 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 iRet,rc; char c,*ptr; ptr = vptr; for(iRet = 1; iRet < maxlen; iRet++) { if((rc == my_read(fd,&c)) == 1) { *ptr++ = c; if(c == '\n') break; } else if(rc == 0) { *ptr = 0; return iRet - 1; } else { return -1; } } *ptr = 0; return iRet; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)