好的,哇,谢谢大家。我非常渴望解决这个问题。感谢所有的回答,尤其是@Stargateur和@user3629249。
好吧,有两件事我需要弄清楚,感谢你们,我现在明白了。
-
我需要使用正确的文件描述符,这似乎很明显,但我总是假设使用连接/接受的connfd或套接字。然而,正如user3629249所说,客户端的connect方法只告诉是否建立了连接,而不是描述符。因此,客户端需要使用套接字中的filedescriptor,在我的示例中是sockfd。
在服务器端,客户端的描述符由accept给定,因此我需要在我的示例中使用connfd。
-
由于我的uni,我已经必须使用一些严格的标志,但是使用更严格的标志真的很有用。我一直对Java非常严格,但忘记了在C语言中也应用这种思想,因为C语言更重要。
所以我在下面发布了我对这个问题的解决方案,再次感谢大家!你让我开心!为了简单起见,头文件没有更改,但是这段代码中还剩下一些东西。如果您使用类似的方法,请检查所有内容的错误,如recv和send方法,并请阅读Stargateur和user3629249的评论,这将帮助您理解我的代码失败的原因,现在可以工作了。
生成文件
CC = /usr/bin/gcc
CFLAGS = -std=c99 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -g -c
SERVER = server
CLIENT = client
all: $(SERVER).c $(CLIENT).c clean compile compile2
compile: $(SERVER).c $(CLIENT).c
gcc $(CFLAGS) $(SERVER).c
gcc $(CFLAGS) $(CLIENT).c
compile2: $(SERVER).o $(CLIENT).o
gcc $(SERVER).o -o $(SERVER)
gcc $(CLIENT).o -o $(CLIENT)
clean: $(SERVER) $(SERVER).o $(CLIENT) $(CLIENT).o
rm $(SERVER) $(SERVER).o
rm $(CLIENT) $(CLIENT).o
客户
#include "common.h"
static char *port = DEFAULT_PORT;
static char *host = DEFAULT_HOST;
int main() {
int s;
struct addrinfo hints, *rp;
memset(&ai, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
s = getaddrinfo(host, port, &hints, &ai);
if(s != 0) error("Couldn't get address info...\n");
for (rp=ai; rp != NULL; rp=rp->ai_next) {
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if(sockfd == -1) continue;
if((connfd = connect(sockfd, rp->ai_addr, rp->ai_addrlen)) != -1) break;
close(sockfd);
}
if(rp == NULL) error("Couldn't connect...\n");
uint8_t msg = 0x00;
for(int i = 0; i < 10; ++i) {
msg=(uint8_t)((int)msg+1);
(void) fprintf(stdout, "Sending message %#X\n", msg);
send(sockfd, &msg, 1, MSG_CONFIRM);
recv(sockfd, &msg, 1, MSG_CONFIRM);
(void) fprintf(stdout, "Recieved from Server %#X\n", msg);
}
free_ressources();
}
服务器
#include "common.h"
static char *port = DEFAULT_PORT;
uint16_t read_from_client();
int main() {
struct addrinfo hints;
memset(&ai, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0;
int res = getaddrinfo(NULL, port, &hints, &ai);
if(res != 0) error("Failed to get addr info: %s\n", gai_strerror(res));
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if(sockfd == -1) error("Couldn't create a socket\n");
int val = 1;
res = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val);
if(res == -1) error("Socket options couldn't be set\n");
res = bind(sockfd, ai->ai_addr, ai->ai_addrlen);
if(res == -1) error("Socket binding failed\n");
res = listen(sockfd, 1);
if(res == -1) error("Listener setup failed\n");
connfd = accept(sockfd, NULL, NULL);
if(connfd == -1) error("Server Accept failed\n");
uint8_t msg = 0x00;
for(int i = 0; i < 10; ++i) {
recv(connfd, &msg, 1, MSG_CONFIRM);
(void) fprintf(stdout, "Recieved from Client %#X\n", msg);
msg = (uint8_t) ((int)msg + 1);
(void) fprintf(stdout, "Sending %#X\n", msg);
send(connfd, &msg, 1, MSG_CONFIRM);
}
free_ressources();
}
因此,输出符合预期。来自/服务器
./server
Recieved from Client 0X1
Sending 0X2
Recieved from Client 0X3
Sending 0X4
Recieved from Client 0X5
Sending 0X6
Recieved from Client 0X7
Sending 0X8
Recieved from Client 0X9
Sending 0XA
Recieved from Client 0XB
Sending 0XC
Recieved from Client 0XD
Sending 0XE
Recieved from Client 0XF
Sending 0X10
Recieved from Client 0X11
Sending 0X12
Recieved from Client 0X13
Sending 0X14
Freeing all ressources...
来自/客户
./client
Sending message 0X1
Recieved from Server 0X2
Sending message 0X3
Recieved from Server 0X4
Sending message 0X5
Recieved from Server 0X6
Sending message 0X7
Recieved from Server 0X8
Sending message 0X9
Recieved from Server 0XA
Sending message 0XB
Recieved from Server 0XC
Sending message 0XD
Recieved from Server 0XE
Sending message 0XF
Recieved from Server 0X10
Sending message 0X11
Recieved from Server 0X12
Sending message 0X13
Recieved from Server 0X14
Freeing all ressources...