【发布时间】:2019-02-01 06:54:47
【问题描述】:
以下代码是使用 UDP 套接字的编程示例。
有3个.c源文件(Client_UDP.c、Server_UDP.c和Message_UDP.c)和1个.h头文件(Prototype.h)。
我希望Server和Client只通过Message_UDP中的函数进行通信。
事情的经过好像是这样的:
- 客户端向服务器发送第一个数据包/消息。
- 服务器收到客户端发来的数据包。
- 服务器尝试发送响应包,但显示错误:
"Error in sendto(): Address family not supported by protocol"。
有人知道为什么吗?我该如何解决这个问题?
Client_UDP.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Prototype.h"
int main(int argc, char * argv[]) {
int fd_socket;
struct sockaddr_in server;
socklen_t length_server = sizeof (server);
fd_socket = socket(AF_INET, SOCK_DGRAM, 0);
Error_A(fd_socket, "Error in socket()");
server.sin_port = htons(8888);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
// send packet to server
function_SEND(fd_socket, server, length_server, "CLIENT");
// receive packet from server
function_RECEIVE(fd_socket, server, length_server, "CLIENT");
close(fd_socket);
return EXIT_SUCCESS;
}
Server_UDP.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Prototype.h"
int main(int argc, char * argv[]) {
int fd_socket;
int rv; // return value
struct sockaddr_in server;
struct sockaddr_in client;
socklen_t length_server = sizeof (server);
socklen_t length_client = sizeof (client);
fd_socket = socket(AF_INET, SOCK_DGRAM, 0);
Error_A(fd_socket, "Errore in socket()");
server.sin_port = htons(8888);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
rv = bind(fd_socket, (struct sockaddr *) &server, length_server);
Error_A(rv, "Error in bind()");
// receive packet from client
function_RECEIVE(fd_socket, client, length_client, "SERVER");
// send packet to client
function_SEND(fd_socket, client, length_client, "SERVER");
close(fd_socket);
return EXIT_SUCCESS;
}
Message_UDP.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Prototype.h"
void Error_A(int return_value, char *error_message) {
if (return_value < 0) {
perror(error_message);
exit(EXIT_FAILURE);
}
}
void function_SEND(int fd_socket, struct sockaddr_in host, int length_host, char *sender) {
int rv; // return value
char packet[100] = "PACKET";
// send packet
rv = sendto(fd_socket, packet, 100, 0, (struct sockaddr *) &host, length_host);
Error_A(rv, "Error in sendto()");
printf("<%s> -- package sent: <%s> \n", sender, packet);
}
void function_RECEIVE(int fd_socket, struct sockaddr_in host, int length_host, char* receiver) {
int rv; // return value
char packet[100] = "";
// receive packet
rv = recvfrom(fd_socket, packet, 100, 0, (struct sockaddr *) &host, &length_host);
Error_A(rv, "Errore in recvfrom()");
printf("<%s> -- packet received: <%s> \n", receiver, packet);
}
原型.h
void Error_A(int return_value, char *error_message);
void function_SEND(int fd_socket, struct sockaddr_in host, int length_host, char *sender);
void function_RECEIVE(int fd_socket, struct sockaddr_in host, int length_host, char* receiver);
这是客户端输出:
CLIENT -- 发送的包:PACKET
这是服务器输出:
SERVER -- 收到的包:PACKET
sendto() 出错:协议不支持地址族
【问题讨论】:
-
与您的问题无关,但您知道端口号应该按网络字节顺序排列吗? IE。你需要使用例如
server.sin_port = htons(8888); -
与您的问题更相关,不要忘记 C 中函数的参数是 按值 传递的。这意味着函数中的参数是传入的原始值的副本。修改副本不会修改原始值。想一想为什么需要在对
recvfrom的调用中将指针 传递给套接字地址结构,并对在C 中模拟通过引用传递 进行一些研究。 -
不抱歉...我现在更正它
-
你的意思是创建一个指向像'struct sockaddr_in *client'这样的结构的指针,然后修改函数'function_RECEIVE()'来传递它吗?
-
不,
client仍然可以像现在一样是结构对象,但您应该修改您的function_RECEIVE以期望指针,并像将结构传递给recvfrom一样传递它。跨度>