因为我是Unix新手,所以我想知道代码是否反映了"unix“风格,以及是否需要添加一些内容来使其健壮。
我希望我没有过度使用assert电话。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define whaterror strerror(errno)
#define PORT 0xbb8
#define BACKLOG 0xf // can't be > 128.
#define BUFFSIZE 0x400
void init_server(struct sockaddr_in* server)
{
assert(server != NULL && "Server pointer can't be null");
server -> sin_family = AF_INET; // use IP.
server -> sin_addr.s_addr = INADDR_ANY; // listen on any address (0.0.0.0).
server -> sin_port = htons(PORT); // listen on PORT.
}
int main()
{
struct sockaddr_in sock_in; // an inbound socket
const int sockfd = socket(PF_INET, SOCK_STREAM, 0); // try to open the socket.
assert(sockfd >= 0 && "Error in opening socket."); // check if socket opened.
memset((char*)&sock_in, 0, sizeof(sock_in)); // reset sock_in to 0
init_server(&sock_in); // initialize server struct
assert(
bind(sockfd, (const struct sockaddr*)&sock_in, sizeof(sock_in)) >= 0 &&
"Port binding failed."
);
assert(
listen(sockfd, BACKLOG) == 0 &&
"Can't listen to the socket specified."
);
int bytes = 0;
char* chunk = memset(malloc(BUFFSIZE), 0, BUFFSIZE);
const int asocfd = accept(sockfd, NULL, 0);
assert(asocfd >= 0 && "Error in accepting socket."); // check if socket opened.
do {
bytes = recv(asocfd, chunk, BUFFSIZE - 1, 0);
memset(bytes == -1 ? chunk : chunk + bytes, 0, BUFFSIZE);
!errno ?
bytes && printf("%d\n%s\n", bytes, chunk)
: fprintf(stderr, "ERRNO: %d [%s]\n", errno, whaterror);
} while (errno == EAGAIN | bytes > 0);
return 0;
}发布于 2021-11-09 17:00:37
我希望我没有过度使用
assert调用
你知道的。assert是一种调试工具。如果定义了NDEBUG宏,则在编译时删除对assert的调用。这是生产代码的通常做法。
#define whaterror strerror(errno),我建议你不要这么做。宏不添加值,只混淆代码。memset(malloc记住,malloc可能会失败。memset(bytes == -1 ? chunk : chunk + bytes, 0, BUFFSIZE);将BUFFSIZE字节设置为0,写入超出分配的空间。你需要BUFFSIZE - bytes。另一方面,没有必要清除chunk的整个尾部。chunk[bytes] = 0;就够了。!errno ?,除了是另一个混淆,是完全错误的。errno是一种检查错误的方法,而不是检测错误的方法。事实上,引用man errno的话,成功的调用永远不会设置errno;一旦设置,它将一直保持到另一个错误发生。recv返回-1是错误的唯一指示。EAGAIN。另一方面,一些错误是暂时的,不应该中断循环。https://codereview.stackexchange.com/questions/269909
复制相似问题