我收到了一些基本上由一个大的 main() 函数组成的 C 代码。我现在正在尝试将该方法展开为更小的函数,以使代码的意图更加清晰。不过,我遇到了一些麻烦:
void main(int argc, char *argv[])
{
if(argc != 3)
{
printf("Usage: table-server <port> <n_lists>\n");
return;
}
int port = atoi(argv[1]), n_lists = atoi(argv[2]);
if(port < 1024 || port > 49151 || n_lists < 1)
{
printf("Invalid args.\n");
return;
}
signal(SIGPIPE, SIG_IGN);
int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in s_addr;
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(port);
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd, (struct sockaddr *)&s_addr, sizeof(s_addr)) < 0)
{
printf("(bind).\n");
return;
}
if(listen(sockfd, SOMAXCONN) < 0)
{
printf("(listen).\n");
return;
}
我可以确定此代码功能中的 4 个主要问题:
- 验证 args 的数量是否正确。
- 从命令行参数获取端口。
- 调用信号(SIGPIPE,SIG_IGN)。
- 实际上尝试与套接字建立连接。
尝试将其重构为小函数时的问题主要与错误处理有关。例如,r 试图提取 1. 的逻辑看起来像这样:
int verify_number_of_args(int argc) {
if (argc != 3) {
printf("...");
return -1;
}
return 0;
}
并称它是这样的
if (verify_number_of_args(argc) == -1) return;
这实际上并没有那么糟糕。现在,对于套接字,这将更加麻烦,因为两者都sockfd
需要s_addr
返回,加上状态返回值:
int sockfd;
struct sockaddr_in* s_addr;
if (create_socket(port, &sockfd, s_addr) == -1)
return;
哪种方式违背了我的主要方法尽可能简单明了的目的。当然,我可以使用文件中的全局变量,.c
但这似乎不是一个好主意。
您通常如何在 C 中处理此类事情?