- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在开发一个 UDP 客户端-服务器程序,我正在逐步实现一些高于当前 UDP 功能的 TCP 功能。需要注意的重要一点是,到目前为止,此代码仅适用于单个客户端(稍后可能会实现更多客户端)。
我已经成功地正确设置了 3 次握手,并且在客户端和服务器之间正确地交换了消息。我使用 SYN-ACK 消息从服务器提取一个新的端口号,客户端将使用该端口号来交换数据(在本例中只是消息)。但是,当客户端完成同步并更改端口后,我无法继续进行消息交换,服务器始终无法收到客户端发送的信息。
这是服务器代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define DOMAIN AF_INET
#define TYPE SOCK_DGRAM
#define PROTOCOL 0
#define BUFFER_SIZE 1025
#define TIMEOUT_SECONDS 1
#define TIMEOUT_MICRO 0
int main(int argc, char* argv[])
{
// INITIALIZATION
int port_sync, port_data;
if (argc < 3)
{
printf("Too few arguments given.\n");
printf("Format: ./server <port_sync> <port_data>\n");
exit(1);
}
else if (argc > 3)
{
printf("Too many arguments given.\n");
printf("Format: ./server <port_sync> <port_data>\n");
exit(1);
}
else
{
port_sync = atoi(argv[1]);
port_data = atoi(argv[2]);
}
// SELECT RETURN
int select_return;
// SOCKET OPTION
int opt = 1;
// FILE DESCRIPTOR
fd_set read_fd_set;
// SYNCHRONIZATION SOCKET
struct sockaddr_in server_addr;
memset((char*)&server_addr, 0, sizeof(server_addr));
int socket_fd;
if ((socket_fd = socket(DOMAIN, TYPE, PROTOCOL)) < 0)
{
perror("[-] Connection error");
exit(1);
}
printf("[+] Synchronization socket created.\n");
if(setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0)
{
perror("[-] setsockopt error");
exit(1);
}
server_addr.sin_family = DOMAIN;
server_addr.sin_port = htons(port_sync);
server_addr.sin_addr.s_addr = INADDR_ANY;
int socket_length = sizeof(server_addr);
// SYNCHRONIZATION SOCKET BIND
if (bind(socket_fd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0)
{
perror("[-] Bind error");
exit(1);
}
printf("[+] Binded successfully to port %d.\n", port_sync);
// DATA SOCKET
struct sockaddr_in server_data_addr;
memset((char*)&server_data_addr, 0, sizeof(server_data_addr));
int socket_data_fd;
if ((socket_data_fd = socket(DOMAIN, TYPE, PROTOCOL)) < 0)
{
perror("[-] Connection error");
exit(1);
}
printf("[+] Data socket created.\n");
if(setsockopt(socket_data_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0)
{
perror("[-] setsockopt error");
exit(1);
}
server_data_addr.sin_family = DOMAIN;
server_data_addr.sin_port = htons(port_data);
server_data_addr.sin_addr.s_addr = INADDR_ANY;
int socket_data_length = sizeof(server_data_addr);
// DATA SOCKET BIND
if (bind(socket_data_fd, (struct sockaddr*) &server_data_addr, sizeof(server_data_addr)) < 0)
{
perror("[-] Bind error");
exit(1);
}
printf("[+] Binded successfully to port %d.\n", port_data);
// CLIENT SYNCHRONIZATION
struct sockaddr_in client_addr;
socklen_t client_length;
// CLIENT DATA
struct sockaddr_in client_data_addr;
socklen_t client_data_length;
char* client_data_IP;
int client_data_port;
// CONNECTION
int online = 1;
int sync_done = 0;
char buffer[BUFFER_SIZE];
while(online)
{
FD_ZERO(&read_fd_set);
if (!sync_done)
{
FD_SET(socket_fd, &read_fd_set);
}
FD_SET(socket_data_fd, &read_fd_set);
if (((select_return = select(10, &read_fd_set, NULL, NULL, NULL))) < 0 && (errno!=EINTR))
{
perror("[-] Select error\n");
exit(1);
}
if (FD_ISSET(socket_fd, &read_fd_set))
{
client_length = sizeof(client_addr);
bzero(buffer, sizeof(buffer));
recvfrom(socket_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr*) &client_addr, &client_length);
if (strstr(buffer, "SYN") != NULL)
{
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "SYN-ACK-%i", port_data);
sendto(socket_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr*) &client_addr, sizeof(client_addr));
recvfrom(socket_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr*) & client_addr, &client_length);
if (strstr(buffer, "ACK"))
{
memset(buffer, 0, sizeof(buffer));
}
}
printf("Finished synchronization\n");
FD_CLR(socket_fd, &read_fd_set);
sync_done = 1;
}
if (FD_ISSET(socket_data_fd, &read_fd_set))
{
int recvfrom_return = recvfrom(socket_data_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr*) & client_data_addr, &client_data_length);
if (strcmp(buffer, "") != 0)
{
client_data_IP = inet_ntoa(client_data_addr.sin_addr);
client_data_port = ntohs(client_data_addr.sin_port);
if (strcmp(buffer, ":exit") == 0)
{
printf("[-] Disconnected from %s:%d\n", client_data_IP, client_data_port);
close(socket_data_fd);
break;
}
else
{
printf("UDP Client: %s\n", buffer);
sendto(socket_data_fd, buffer, recvfrom_return, 0, (struct sockaddr*) & client_data_addr, client_data_length);
memset(buffer, 0, sizeof(buffer));
bzero(buffer, sizeof(buffer));
}
}
}
}
return 0;
}
这是客户端代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define DOMAIN AF_INET
#define TYPE SOCK_DGRAM
#define PROTOCOL 0
#define BUFFER_SIZE 1025
#define TIMEOUT_SECONDS 1
#define TIMEOUT_MICRO 0
int get_data_port(char* buffer)
{
char delim[] = "-";
char port[20];
char* ptr = strtok(buffer, delim); // ptr = "SYN"
ptr = strtok(NULL, delim); // ptr = "ACK"
ptr = strtok(NULL, delim); // ptr = port_data
strcpy(port, ptr);
int port_data = atoi(port);
return port_data;
}
int main(int argc, char* argv[])
{
// INITIALIZATION
int port_sync, port_data;
char addr[15];
if (argc < 3)
{
printf("Too few arguments given.\n");
printf("Format: ./client <adresseIP> <port>\n");
exit(1);
}
else if (argc > 3)
{
printf("Too many arguments given.\n");
printf("Format: ./client <adresseIP> <port>\n");
exit(1);
}
else
{
strcpy(addr, argv[1]);
port_sync = atoi(argv[2]);
}
// SOCKET OPTION
int opt = 1;
// SYNCHRONIZATION SOCKET
struct sockaddr_in client_addr;
memset((char*)&client_addr, 0, sizeof(client_addr));
int socket_fd;
if ((socket_fd = socket(DOMAIN, TYPE, PROTOCOL)) < 0)
{
perror("[-] Connection error");
exit(1);
}
printf("[+] Synchronization socket created.\n");
if(setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0)
{
perror("[-] setsockopt error");
exit(1);
}
client_addr.sin_family = DOMAIN;
client_addr.sin_port = htons(port_sync);
client_addr.sin_addr.s_addr = INADDR_ANY;
socklen_t socket_length = sizeof(client_addr);
// CONNECTION
int online = 1;
int sync_done = 0;
char buffer[BUFFER_SIZE];
while (online)
{
if (!sync_done)
{
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "SYN");
sendto(socket_fd, buffer, strlen(buffer), 0, (struct sockaddr*) & client_addr, sizeof(client_addr));
recvfrom(socket_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr*) & client_addr, &socket_length);
if (strstr(buffer, "SYN-ACK") != NULL)
{
port_data = get_data_port(buffer);
printf("New port: %d\n", port_data);
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "ACK");
sendto(socket_fd, buffer, strlen(buffer), 0, (struct sockaddr*) & client_addr, sizeof(client_addr));
}
memset(buffer, 0, sizeof(buffer));
printf("Finished synchronization\n");
client_addr.sin_port = htons(port_data);
sync_done = 1;
socket_length = sizeof(client_addr);
}
else
{
printf("UDP Client: ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strcspn(buffer, "\n")] = 0;
sendto(socket_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)& client_addr, sizeof(client_addr));
if (strcmp(buffer, ":exit") == 0)
{
close(socket_fd);
printf("[-] Disconnected from server\n");
exit(1);
}
int recvfrom_return;
if ((recvfrom_return = recvfrom(socket_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) & client_addr, &socket_length)) < 0)
{
perror("[-] Data reception error");
}
else
{
buffer[recvfrom_return] = 0;
printf("Server: %s\n", buffer);
}
}
}
return 0;
}
我已经检查了许多关于如何通过套接字通信更改端口的在线示例和教程,我感觉好像我已经遵循了所有指南,但显然我遗漏了一些东西。
编辑
我的问题是,在我使用 client_addr.sin_port = htons(port_data);
更改端口后,服务器永远不会收到客户端消息。 。我检查了服务器端,代码进入第二个if(FD_ISSET...)
陈述。我尚未查明导致消息未到达的原因。
提前致谢,请毫不犹豫地指出这是否重复(并链接重复的问题)!
最佳答案
我需要初始化两个地址长度,如下所示:
socklen_t client_length = sizeof(client_addr);
socklen_t client_data_length = sizeof(client_data_addr);
关于c - 端口更改后 UDP 客户端服务器无法交换消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58717598/
我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我的第一个想法如下: 我在服务器上创建了一个中央 ServerSocket,所有应用程序都可以连接到该服务器。
我正在 Unity 中构建多人游戏。为此,我必须将一些值从客户端发送到两个或多个通过服务器连接的客户端。我想将其构建为服务器真实游戏。客户端将使用 Android,他们的数据将通过服务器同步(可能是一
练习 C 网络编程:我正在编写一个简单的 TCP 客户端-服务器应用程序,它应该将消息(在每个客户端的单独线程中)作为字符串从服务器发送到客户端并在客户端(稍后将成为控制台商店应用程序)。我首先发送消
我使用证书身份验证设置了 AWS Client VPN。我正在为客户端-客户端访问系统进行设置,基本上如 this AWS scenario/example 中所述.一切正常,如果我知道他们的 IP
我正在开发一个小型客户端1/客户端2、服务器(线程)TCP 游戏。在尝试处理延迟问题时,我意识到我的 transmitState() 中存在缺陷。它强制将不必要的信息传递到通讯流中,从而造成迟缓,将汽
来自文档:Configurable token lifetimes in Azure Active Directory (Public Preview) 它提到“ secret 客户端”,刷新 tok
Apollo 客户端开发工具无法连接到我的应用程序。我已在 ApolloClient 构造函数中将 connectToDevTools 传递为 true,但没有任何 react 。我也试过this p
我想在 Pod 内使用 Fabric8 kubernetes 客户端 (java)。如何获取部署集群的 kubernetes 客户端? 我可以使用该集群的 kubeconfig 文件获取任何集群的配置
我正在阅读 the security issue with Log4j我了解此产品受此漏洞影响。但是 Oracle 客户端 11.2 和 12 是否受此问题影响? 我找不到这些产品是否使用任何 Log
Eureka 服务器设置 pom.xml 1.8 Hoxton.SR1 org.springframework.cloud spring
我有一个点对点(客户端/服务器)设置(通过本地 LAN),它使用 Netty,一个 Java 网络框架。我使用原始 TCP/IP(例如,没有 HTTP)进行通信和传输。现在,根据要求,我们希望转向 T
上一篇已经实现了ModbusTcp服务器和8个主要的功能码,只是还没有实现错误处理功能。 但是在测试客户端时却发现了上一篇的一个错误,那就是写数据成功,服务器不需要响应。 接下来要做的就是实现Modb
有没有办法将二维十六进制代码数组转换为 png 图像? 数组看起来像这样(只是更大) [ [ '#FF0000', '#00FF00' ], [ '#0000FF'
我是套接字编程的新手。每次我运行客户端程序时,它都会说“无法连接到服务器”。谁能告诉我我在哪里犯了错误。任何帮助将不胜感激。 这是client.c #include #include #inclu
我们在UNIX环境下制作了简单的client.c和server.c程序。我们使用它来传输一个简单的文本文件,首先打开它,然后读取它并使用 open、read 和 send 系统调用发送;在客户端,我接
当我的程序来自 my previous question正在响应客户端,它应该发送加密消息。 当客户端连接时,它会发送一条类似“YourMessage”的消息。现在我想做的是,当客户端连接时,应该以某
我正在使用 C 和 putty 编写客户端/服务器程序。两个 c 文件位于同一系统上。 我目前在向客户端写回其正在使用的框架以及打印我的框架时遇到问题。它打印出 3 0 9 8,但随后开始打印 134
我正在使用 C 中的 select() 制作一个模拟快餐或其他任何东西的客户端服务器。 我有客户随机点 1-5 种“食物”。服务器每 30 秒决定一次。所有客户最喜欢的食物是什么?他为那些客户提供服务
对于单机游戏,基本的游戏循环是(来源:维基百科) while( user doesn't exit ) check for user input run AI move enemies
1、CentOS安装TortoiseSVN 复制代码 代码如下: yum install -y subversion 2、SVN客户端命令
我是一名优秀的程序员,十分优秀!