【发布时间】:2017-03-29 04:08:15
【问题描述】:
我一直在尝试建立一个简单的 UDP 聊天服务器来学习如何制作我自己的聊天室,对于初学者来说,我只是掌握了与共享相同 IP/端口的客户端运行 UDP 服务器的窍门。服务器。客户端以结构的形式发送数据。 服务器应该有 3 种可能性,一个新的客户端加入,它通过匹配命令 JOIN 来识别,或者客户端通过匹配命令 QUIT 退出,或者通过不匹配这两者来识别消息......
这些命令存储在客户端以(ID,COMMAND,域/端口)的形式发送的结构中。 除非它是一条消息,否则它将是(ID、域/端口、消息)。我已经在我的代码中处理了。
客户端 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;
}
【问题讨论】:
标签: c networking server udp chat