Мне вручили некоторый код C, который в основном состоит из большой функции main(). Сейчас я пытаюсь разбить метод на более мелкие функции, чтобы сделать код более понятным. У меня есть некоторые проблемы, хотя:
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 основные проблемы в функции этого кода:
- Проверка правильности количества аргументов.
- Получение из аргументов командной строки порта.
- Сигнал вызова (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?
[error-handling] [c]
. - person Mike Sherrill 'Cat Recall'   schedule 14.11.2011