实现TFTP时候遇到的坑
TFTP是一个非常简单的用于传输文件的协议。ietf.org/rfc/rfc1350.txt
recvfrom和recv函数
实现下载时一开始我用的是recv
函数来获取从服务器发来的数据,但是发现一旦第一个数据包来了之后,给服务器返回一个ACK包后,立马服务器就返回一个错误包:
1 2 3
| ERROR: [ERROR_CODE]:4 [ERROR_MSG]:Illegal TFTP operation
|
这个错误搞了我很久,差点心态搞崩,目前暂时不清楚原因。
参考:
- 项目概览 - tftpx - GitCode
- W.Richard.Stevens 的 TCP/IP Illustrated Volume 1: The Protocols(TCP/IP详解 卷1:协议).
实现在线聊天平台遇到的坑
makefile问题
我有个用C语言实现在线聊天的工程,这个工程有服务器端和客户端,我放在工程目录下的server和client中,还有个放头文件的inc目录,src目录下还有两个代码公共的.c文件
目录结构如下:
1 2 3 4 5 6 7 8 9 10 11 12
| project_root/ |-- inc/ | |-- loger.h | |-- linklist.h |-- src/ | |-- loger.c | |-- linklist.c |-- server | |-- server.c |-- client | |-- client.c |-- Makefile
|
我的makefile文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
CC = gcc
CFLAGS = -Wall -Werror
BUILD_DIR = build
SRC_DIR = src INC_DIR = inc SERVER_DIR = server CLIENT_DIR = client
SERVER_EXE = $(BUILD_DIR)/server CLIENT_EXE = $(BUILD_DIR)/client
COMMON_SRC = $(wildcard $(SRC_DIR)/*.c)
SERVER_SRC = $(SERVER_DIR)/server.c CLIENT_SRC = $(CLIENT_DIR)/client.c
SERVER_OBJ = $(BUILD_DIR)/server.o CLIENT_OBJ = $(BUILD_DIR)/client.o COMMON_OBJ = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(COMMON_SRC))
$(shell mkdir -p $(BUILD_DIR))
all: server client
server: $(SERVER_EXE)
$(SERVER_EXE): $(SERVER_OBJ) $(COMMON_OBJ) $(CC) $(CFLAGS) -o $@ $^
$(SERVER_OBJ): $(SERVER_SRC) $(CC) $(CFLAGS) -I$(INC_DIR) -c $< -o $@
client: $(CLIENT_EXE)
$(CLIENT_EXE): $(CLIENT_OBJ) $(COMMON_OBJ) $(CC) $(CFLAGS) -o $@ $^
$(CLIENT_OBJ): $(CLIENT_SRC) $(CC) $(CFLAGS) -I$(INC_DIR) -c $< -o $@
$(COMMON_OBJ): $(COMMON_SRC) $(CC) $(CFLAGS) -I$(INC_DIR) -c $< -o $@
clean: rm -rf $(BUILD_DIR)/*.o $(SERVER_EXE) $(CLIENT_EXE)
.PHONY: all server client clean
|
现在的问题是,我编译的时候显示linklist内部的函数multiple definition,我没有重复定义,也启用了头文件保护,这是为啥?
下面是ChatGPT的解答:
问题出现在多次定义相同函数或变量时,通常在连接阶段,链接器会遇到不同目标文件中相同函数或变量的多次定义。在你的Makefile中,你有一个COMMON_SRC变量,其中包含了src目录中的所有源文件。这个变量然后用于创建COMMON_OBJ变量。但是,当你单独编译每个源文件时,COMMON_OBJ变量并未被使用。相反,每个单独的源文件都被单独编译。
为了解决这个问题,你应该修改COMMON_OBJ的规则,使用模式规则来分别编译每个源文件。以下是修改后的规则:
1 2 3
| $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(CC) $(CFLAGS) -I$(INC_DIR) -c $< -o $@
|
用上述规则替换Makefile中现有的$(COMMON_OBJ)规则。这样,src目录中的每个源文件将被单独编译成自己的目标文件,链接器将不会遇到相同函数的多次定义。
在Makefile中找到相应的行,并进行修改。修改后,尝试重新构建项目,多次定义的问题应该会得到解决。