我一直在试图设置一个简单的UDP聊天服务器来学习如何使自己的聊天室,对于初学者,我只是得到与共享客户端运行UDP服务器的挂起与服务器相同的IP /端口。客户端以结构形式发送数据。 有3种可能性,一个服务器应该期望,一个新的客户端加入,它认识到通过匹配命令JOIN,或者通过匹配命令QUIT来匹配客户端,或者通过匹配这两种匹配的消息...使用消息结构的UDP聊天服务器
这些命令存储在客户端以(ID,COMMAND,Domain/Port)形式发送的结构中。除非它是一条消息,否则它将是(ID,Domain/Port,Message)。我在我的代码中处理了哪些内容。
客户100%的工作,因为它提供给我作为一个来源,但我不能使用它,因为它是可执行的,所以问题来自我的服务器。我制作了一个调试工具来检查发生了什么问题,这似乎是客户端加入时的情况,并且我向客户证实我已经接受他,客户端永远不会收到确认网络,这是因为我没有格式化它正确。 它应该类似Received: <1 JOIN loki>
然后Sent: <1 JOIN loki>
其中带括号的3个变量是结构部分..但它不存储正确的域/端口部分的第二个字符串...所以当我运行调试工具时,我得到Received: <1 JOIN>
,SENT <1 JOIN>
。 那么为什么它会这样做,就像我解析结构到我的缓冲区结构然后发送它。它怎么没有正确捕获域部分?
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define LOCAL_PORT 2317
#define MAX_LEN 255
struct message {
int cid; /* Connection ID */
char str1[MAX_LEN]; /* JOIN, QUIT, or client-domain-name */
char str2[MAX_LEN]; /* user-string or client-domain-name */
};
int rcv_cid;
int rc,sd;
struct message my_msg, rcv_msg;
char rcv_str1[MAX_LEN];
char rcv_str2[MAX_LEN];
int main(int argc, char* argv[]) {
struct sockaddr_in servAddr;
int servLen = sizeof(servAddr);
int IDlist [] = {0,0,0,0,0,0,0,0,0,0} ;
int i=0; int port;
/* Socket Creation */
if(argc < 3){
printf("usage : ./chatServer <port#> <debug_option:0 or 1>\n");
exit(1);
}
sd = socket(AF_INET, SOCK_DGRAM , 0);
if(sd<0) {
printf("%s , cannot open socket \n",argv[0]);
exit(1);
}
/* bind argv[1] server port */
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* bind argv[1] which is what the user provides */
port = atoi(argv[1]);
servAddr.sin_port = htons(port);
rc= bind(sd, (struct sockaddr *) &servAddr , sizeof (servAddr));
if(rc <0){
printf("%s: cannot bind port number %d \n", argv[0], port);
exit (1);
}
printf("%s: waiting for data on port UDP %d \n", argv[0], port);
while(1) {
/* grab incoming request */
rc = recvfrom(sd, &rcv_msg, MAX_LEN, 0, (struct sockaddr *) &servAddr, &servLen);
printf(" %s \n" , rcv_msg.str2);
if(atoi(argv[2]) == 1){
printf("DEBUG: Receiving <%d %s %s>\n",rcv_msg.cid,rcv_msg.str1,rcv_msg.str2);
}
if(strcmp(rcv_msg.str1,"join") == 0) {
for(i =1; i< 11 ; i ++){
if(IDlist[i] == rcv_msg.cid){
rcv_msg.cid = i;
IDlist[i] = rcv_msg.cid;
break;}
}
/* for(j = 0, j < 10 ; j ++){ */
/* if(IDlist[j] != IDlist [i]){ */
my_msg.cid = i;
strcpy(my_msg.str1, "JOIN");
strcpy(my_msg.str2, rcv_msg.str2);
if(atoi(argv[2]) == 1){
printf("DEBUG: Sending <%d %s %s>\n",my_msg.cid,my_msg.str1,my_msg.str2);
}
rc = sendto(sd, &my_msg, sizeof(my_msg)+1, 0,
(struct sockaddr *) &servAddr,
sizeof(servAddr));
/* compose a temp struct , then send it to each ID on the list except the one we just added */
}
if(strcmp(rcv_msg.str1,"QUIT") == 0) {
for(i=0;i<10 ; i++){
if(rcv_msg.cid == IDlist[i])
IDlist [i] = 0;
}
my_msg.cid = rcv_msg.cid;
strcpy(my_msg.str1, "QUIT");
strcpy(my_msg.str2, rcv_msg.str2); /*my name Nodname contains domain and port number built into C library */
if(atoi(argv[2]) == 1){
printf("DEBUG: Sending <%d %s %s>\n",my_msg.cid,my_msg.str1,my_msg.str2);
}
rc = sendto(sd, &my_msg, sizeof(my_msg)+1, 0,
(struct sockaddr *) &servAddr,
sizeof(servAddr));
}
else {
my_msg.cid = rcv_msg.cid;
strcpy(my_msg.str1, rcv_msg.str1);
strcpy(my_msg.str2, rcv_msg.str2); /*my name Nodname contains domain and port number built into C library */
if(atoi(argv[2]) == 1){
printf("DEBUG: Sending <%d %s %s>\n",my_msg.cid,my_msg.str1,my_msg.str2);
}
rc = sendto(sd, &my_msg, sizeof(my_msg)+1, 0,
(struct sockaddr *) &servAddr,
sizeof(servAddr));
}
}
return 0;
}
我试过了,但它仍然没有工作:(。 –
@ MohammedAl-Huneidi然后客户端不发送的样子觉得它的数据。我发现在你的代码两个错误指出但是没有任何客户端代码,我无法构建测试用例和w/o测试用例,我不能告诉你问题出在哪里。 – Mecki
@ MohammedAl-Huneidi还添加了一个测试用例,其中您可以直接在线测试固定代码它只是正常工作,所以如果你仍然有问题,你没有正确添加我指出的所有修复或错误是在客户端。 – Mecki