首页 > 编程语言 >出错处理封装函数 - 使Socket编程更安全可靠

出错处理封装函数 - 使Socket编程更安全可靠

时间:2023-12-21 10:32:08浏览次数:25  
标签:封装 Socket 安全可靠 int ptr fd 出错 处理函数


导语

       在Socket编程中,错误处理是至关重要的一环。通过封装出错处理函数,我们可以提高代码的可读性和可维护性,增加代码的重用性,统一管理错误信息,提高系统的稳定性和可靠性。本文将详细介绍为什么要进行出错处理函数的封装,并探讨如何使Socket编程更加安全可靠。     

正文

为什么要进行出错处理函数的封装

        在Socket编程中,错误处理是不可或缺的一部分。网络操作中可能会出现各种错误,如连接中断、超时、资源不足等。如果没有进行适当的错误处理,程序可能会崩溃或出现意外行为。以下是为什么要进行出错处理函数的封装的几个重要原因:

  1. 代码可读性和可维护性:封装出错处理函数可以将错误处理的逻辑从主程序中分离出来,使得主程序的代码更加简洁和易读。主程序只需要关注业务逻辑,而不必过多关注错误处理的细节。这样可以提高代码的可读性,使得代码更易于理解和维护。
  2. 代码重用性:在Socket编程中,很多操作都需要进行错误处理,如建立连接、发送数据、接收数据等。如果每次都在主程序中手动编写错误处理的代码,会导致代码冗余,增加了代码的维护成本。通过封装出错处理函数,可以将错误处理的代码封装起来,提高代码的重用性。这样可以避免重复编写相同的错误处理代码,减少了代码的冗余性。
  3. 错误信息的统一管理:封装出错处理函数可以统一管理错误信息。在函数内部,可以定义一套错误码和错误描述,用于标识和描述不同类型的错误。当出错发生时,可以根据错误码打印相应的错误描述,帮助开发人员快速定位问题。这样可以提高开发效率,减少故障排查的时间。
  4. 异常处理和系统稳定性:在Socket编程中,系统调用和网络操作可能会出现各种错误,如连接中断、超时、资源不足等。如果没有进行适当的错误处理,程序可能会崩溃或出现意外行为。通过封装出错处理函数,可以及时捕获并处理这些错误,保证程序的健壮性和稳定性。这样可以提高系统的可靠性,减少系统故障的风险。

如何使Socket编程更安全可靠

        在Socket编程中,通过封装出错处理函数,我们可以使其更加安全可靠。以下是一些建议:

  1. 错误码和错误描述的定义:在封装出错处理函数时,可以定义一套错误码和错误描述,用于标识和描述不同类型的错误。错误码应该具有一定的层级结构,以便快速定位问题。错误描述应该清晰明了,帮助开发人员快速理解错误的原因和解决方法。
  2. 异常处理机制:在封装出错处理函数时,应该考虑引入异常处理机制。通过捕获异常,我们可以及时处理错误,并进行相应的补救措施。异常处理可以避免程序崩溃或出现意外行为,提高系统的稳定性。
  3. 错误信息的打印和记录:在封装出错处理函数时,应该考虑将错误信息打印和记录下来。错误信息可以包括错误码、错误描述、错误发生的位置等。这样可以帮助开发人员快速定位问题,进行故障排查和修复。
  4. 错误恢复和重试机制:在封装出错处理函数时,应该考虑引入错误恢复和重试机制。当出现错误时,我们可以尝试进行错误恢复,以使程序继续执行。如果错误无法恢复,我们可以进行重试操作,以提高操作的成功率。

Socket编程函数出错处理封装分享

 wrap.c

#include <stdlib.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;
	if ((n = connect(fd, sa, salen)) < 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;
}
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;
			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 -1;
	}
	*ptr = 0;
	return n;
}

出错处理封装函数 - 使Socket编程更安全可靠_Linux

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

出错处理封装函数 - 使Socket编程更安全可靠_Linux_02

结论

        通过封装出错处理函数,我们可以提高代码的可读性和可维护性,增加代码的重用性,统一管理错误信息,提高系统的稳定性和可靠性。在Socket编程中,错误处理是不可或缺的一环。通过合理的错误处理机制,我们可以使Socket编程更加安全可靠。在实际开发中,我们应该充分利用出错处理函数的封装,以提高开发效率和减少故障排查的时间。


标签:封装,Socket,安全可靠,int,ptr,fd,出错,处理函数
From: https://blog.51cto.com/u_16158769/8918168

相关文章

  • Socket.D 基于消息的响应式应用层网络协议
    首先根据Socket.D官网的副标题,Socket.D的自我定义是:基于事件和语义消息流的网络应用协议。官网定义的特点是:基于事件,每个消息都可事件路由所谓语义,通过元信息进行语义描述流关联性,有相关的消息会串成一个流语言无关,使用二进制输传数据(支持tcp,ws,udp)。支持多语言、......
  • Vite4+Typescript+Vue3+Pinia 从零搭建(7) - request封装
    项目代码同步至码云weiz-vue3-template基于axios封装请求,支持多域名请求地址安装npmiaxios封装utils目录下新建request文件夹,并新建index.ts、request.ts和status.ts文件。1.status.ts文件主要是封装状态码exportconstErrMessage=(status:number|s......
  • Mysql以及TCP socket的C++代码
    在使用socket编写tcp的C++程序时,遇到了一个问题:那就bind冲突了,分析原因:是因为std中有bind函数,而socket中也有,但是没有报重复定义的错误,这就有一点难办了。百度了一下:发现只要使用::bind就可以调用socket的bind。下面把这个套接字socket的server端代码贴出来:staticvoid*serv......
  • websocket++
    一、介绍版本:WebSocket++(0.8.2)1、readme.md参照readme.mdWebSocket++是一个只有头文件(只有hpp文件)的c++库,它实现了RFC6455(WebSocket协议)。它允许将WebSocket客户端和服务端集成到c++程序中。它使用了可互换的网络传输模块,包括:基于原始字符缓冲区的模块基于c++的iostre......
  • 【网关开发】Openresty使用cosocket API 发送http与tcp网络请求
    背景为网关提供健康检查功能时需要对节点发送http或者tcp探活请求。Openresty提供cosocket来处理非阻塞IO。实现跟工程结合在一起,这里简单拼接数据结构localfunction__default_check_alive(status)returnstatus>=200andstatus<=299endlocalfunctiondebug_c......
  • 接口自动化之excel读写封装
    本次封装基于openpyxl进行的二次封装安装openpyxlpipinstallopenpyxl封装ExcelReader采用yield的方式返回数据,减少内存的占用classExcelReader:def__init__(self,filename):self._excel:Workbook=load_workbook(filename,read_only=True)d......
  • go的封装、继承与多态的使用
    目录一、封装1.1公有封装1.2私有封装1.2.1工厂函数解析1.2.2&与*指针使用描述1.3深度封装二、继承与多态2.1继承与多态案例2.1.1继承代码分析2.1.2结构体实例化2.1.3多态代码分析一、封装​ 在Go语言中,封装是一种将数据和操作数据的方法组织在一起的概念。封装的目的......
  • 接口自动化之响应数据封装
    在使用requests实现接口自动化时,接口响应的数据没有代码提示,要获取某个接口字段就需要通过[xxx]的方式来获取,实际开发过程中希望能通过.的方式来获取到某个接口响应属性。方式一、使用dataclassdataclass是python3.7新推出的特性之一fromdataclassesimportdataclass@......
  • WebSocket和Socket的区别
    区别总结协议不同Socket是基于传输层TCP协议的,而Websocket是基于HTTP协议的。Socket通信是通过Socket套接字来实现的,而Websocket通信是通过HTTP的握手过程实现的。持久化连接传统的Socket通信是基于短连接的,通信完成后即断开连接。Websocket将HTTP协议升......
  • 从零开始封装 vue 组件
    对于学习Vue的同学来说,封装vue组件是实现代码复用的重要一环。在Vue官网中非常详细地介绍了vue组件的相关知识,我这里简单摘取使用最频繁的几个知识点,带大家快速入门vue组件的使用。快速入门我们假设在页面上有很多地方都要用到一个计数器,与其在每个地方都实现计数器功......