问题是让UDP服务器将数据发送到已经与服务器建立连接的客户端阵列。所有客户端IP都存储在服务器端链表中,但由于某种原因,我只能发送响应,而且只能发送到客户端的最后连接。
所以我想要实现的基本描述是:
很少有客户建立连接,我可以看到他们的消息
每个客户的IP都存储在链表
server.c
#include "server.h"
#include "linkedList.h"
volatile sig_atomic_t dones = 0;
void server(){
pthread_t r, s;
int server_d;
struct sockaddr_in server, client;
struct params args;
linkedList** iter = getIteratorList();
if((server_d = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
perror("\nsocket");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
bzero(server.sin_zero, 8);
args.client = &client;
args.server_d = &server_d;
args.iter = iter;
if(bind(server_d, (struct sockaddr*)&server, sizeof(struct sockaddr)) == -1){
perror("\nbind");
exit(-1);
}
pthread_create(&r, NULL, receives, (void*)&args);
pthread_create(&s, NULL, sends, (void*)&args);
pthread_join(s, NULL);
}
void* receives(void* data){
int flag = 0;
struct params* args = data;
int* server_d = args->server_d;
struct sockaddr_in* client = args->client;
linkedList** iter = args->iter;
unsigned int length = sizeof(struct sockaddr_in);
char buffer[BUFFER_MAX];
struct sockaddr_in tmp;
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = terms;
sigaction(SIGINT, &action, NULL);
bzero(buffer, BUFFER_MAX);
while(!dones){
if(flag == 0){
if(recvfrom(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)client, &length) > 0){
flag = 1;
decrypt(buffer);
printf("[%s]:%s", inet_ntoa(client->sin_addr), buffer);
//some new staff
if(checkList(inet_ntoa(client->sin_addr)) != 1){
addList(*client);
printf("[DEBUG]clients IP is stored. size of LL: %d\n", sizeList());
}
if(sizeList() > 1){
beginList();
for(int i = 0; i < sizeList(); i++){
printf("[DEBUG]Stored IP[%d]: %s\n", i, (*iter)->address);
nextList();
}
}
beginList();
for(int i = 0; i < sizeList(); i++){
if (strcmp((*iter)->address, inet_ntoa(client->sin_addr)) != 0){
printf("[DEBUG]there is a client to send a message to. message: %s", buffer);
printf("[DEBUG]resend: %s --> %s\n",inet_ntoa(client->sin_addr), (*iter)->address);
tmp.sin_addr.s_addr = inet_addr((*iter)->address);
tmp.sin_family = client->sin_family;
tmp.sin_port = client->sin_port;
bzero(tmp.sin_zero, 8);
printf("[DEBUG]IP in tmp.sin_addr: %s\n", inet_ntoa(tmp.sin_addr));
printf("[DEBUG]IP in client->sin_addr: %s\n", inet_ntoa(client->sin_addr));
printf("[DEBUG]message send: %d\n", (int)sendto(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)&tmp, sizeof(struct sockaddr_in)));
nextList();
}else{
nextList();
}
}
// end of new staff
}
bzero(buffer, BUFFER_MAX);
}else{
if(recvfrom(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)client, &length) == 0){
flag = 0;
}else{
decrypt(buffer);
printf("[%s]:%s", inet_ntoa(client->sin_addr), buffer);
//some new staff
if(checkList(inet_ntoa(client->sin_addr)) != 1){
addList(*client);
printf("[DEBUG]clients IP is stored. size of LL: %d\n", sizeList());
}
if(sizeList() > 1){
beginList();
for(int i = 0; i < sizeList(); i++){
printf("[DEBUG]Stored IP[%d]: %s\n", i, (*iter)->address);
nextList();
}
}
beginList();
for(int i = 0; i < sizeList(); i++){
if (strcmp((*iter)->address, inet_ntoa(client->sin_addr)) != 0){
printf("[DEBUG]there is a client to send a message to. message: %s", buffer);
printf("[DEBUG]resend: %s --> %s\n",inet_ntoa(client->sin_addr), (*iter)->address);
tmp.sin_addr.s_addr = inet_addr((*iter)->address);
tmp.sin_family = client->sin_family;
tmp.sin_port = client->sin_port;
bzero(tmp.sin_zero, 8);
printf("[DEBUG]IP in tmp.sin_addr: %s\n", inet_ntoa(tmp.sin_addr));
printf("[DEBUG]IP in client->sin_addr: %s\n", inet_ntoa(client->sin_addr));
printf("[DEBUG]message send: %d\n", (int)sendto(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)&tmp, sizeof(struct sockaddr_in)));
nextList();
}else{
nextList();
}
}
// end of new staff
}
bzero(buffer, BUFFER_MAX);
}
}
printf("Server terminated.\n");
return NULL;
}
void* sends(void* data){
struct params* args = data;
int* server_d = args->server_d;
struct sockaddr_in* client = args->client;
linkedList** iter = args->iter;
char buffer[BUFFER_MAX];
struct sockaddr_in tmp;
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = terms;
sigaction(SIGINT, &action, NULL);
while(!dones){
bzero(buffer, BUFFER_MAX);
fgets(buffer, BUFFER_MAX - 1, stdin);
encrypt(buffer);
/*
if(sendto(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)client, sizeof(struct sockaddr_in)) == -1){
printf("Message was not sent...\n");
}
*/
tmp.sin_addr.s_addr = client->sin_addr.s_addr;
tmp.sin_family = client->sin_family;
tmp.sin_port = client->sin_port;
bzero(tmp.sin_zero, 8);
beginList();
for(int i = 0; i < sizeList(); i++){
tmp.sin_addr.s_addr = inet_addr((*iter)->address);
printf("[DEBUG]sending to address: %s\n", inet_ntoa(tmp.sin_addr));
sendto(*server_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)&tmp, sizeof(struct sockaddr_in));
nextList();
}
}
printf("Server terminated.\n");
return NULL;
}
void terms(int signum){
dones = 1;
if(clearList() == 0) printf("\n\nLinkedList was succesfully deleted.\n");
printf("\nTerminating server...\n");
}
server.h
#ifndef SERVER_H_
#define SERVER_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include "const.h"
#include "encrypt.h"
#include "linkedList.h"
struct params{
struct sockaddr_in* client;
int* server_d;
linkedList** iter;
};
volatile sig_atomic_t dones;
void server();
void* receives(void*);
void* sends(void*);
void terms(int);
#endif
linkedList.h
#ifndef LINKED_LIST_
#define LINKED_LIST_
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
typedef struct ll{
int socket;
char* address;
struct ll* next;
struct ll* prev;
} linkedList;
linkedList* initList(struct sockaddr_in);
linkedList* addList(struct sockaddr_in);
linkedList* removeList(char*);
unsigned short int clearList();
unsigned short int sizeList();
linkedList* nextList();
linkedList* prevList();
linkedList* beginList();
linkedList* endList();
linkedList** getIteratorList();
unsigned short int checkList(char*);
#endif
linkedList.c
#include "linkedList.h"
static linkedList* iterator = NULL;
linkedList* initList(struct sockaddr_in p_new){
iterator = (linkedList*) malloc(sizeof(linkedList));
if(iterator == NULL) return NULL;
iterator->next = NULL;
iterator->prev = NULL;
iterator->address = (char*)malloc(sizeof(char)*16);
strcpy(iterator->address, inet_ntoa(p_new.sin_addr));
return iterator;
}
linkedList* addList(struct sockaddr_in p_new){
if(iterator == NULL){
return initList(p_new);
}
endList();
iterator->next = (linkedList*) malloc(sizeof(linkedList));
if(iterator->next == NULL) return NULL;
iterator->next->next = NULL;
iterator->next->prev = iterator;
iterator->next->address = (char*)malloc(sizeof(char)*16);
strcpy(iterator->next->address, inet_ntoa(p_new.sin_addr));
return iterator = iterator->next;
}
linkedList* removeList(char* p_address){
beginList();
for(int i = 0; i < sizeList(); i++){
if(strcmp(iterator->address, p_address) == 0){
if(iterator->prev == NULL){
iterator = iterator->next;
free(iterator->prev->address);
free(iterator->prev);
iterator->prev = NULL;
return iterator;
}else if(iterator->next == NULL){
iterator = iterator->prev;
free(iterator->next->address);
free(iterator->next);
iterator->next = NULL;
return iterator;
}else{
linkedList* tmp = iterator->next;
iterator->prev->next = iterator->next;
iterator->next->prev = iterator->prev;
free(iterator->address);
free(iterator);
return iterator = tmp;
}
}else{
nextList();
}
}
beginList();
return iterator;
}
unsigned short int clearList(){
if (iterator == NULL) return 404;
endList();
while( (iterator->next != NULL && iterator->prev != NULL) ){
iterator = iterator->prev;
free(iterator->next->address);
free(iterator->next);
iterator->next = NULL;
}
free(iterator);
iterator = NULL;
return 0;
}
unsigned short int sizeList(){
unsigned short int size = 0;
unsigned int tmp_range = 0;
if(iterator == NULL) return size;
while(iterator->prev != NULL){
tmp_range++;
prevList();
}
while(iterator->next != NULL){
size++;
nextList();
}
size++;
beginList();
for(int i = 0; i < tmp_range; i++){
nextList();
}
return size;
}
linkedList* nextList(){
if (iterator == NULL) return NULL;
if(iterator->next == NULL) return iterator; else return iterator = iterator->next;
}
linkedList* prevList(){
if (iterator == NULL) return NULL;
if(iterator->prev == NULL) return iterator; else return iterator = iterator->prev;
}
linkedList* beginList(){
if (iterator == NULL) return NULL;
while(iterator->prev != NULL){
prevList();
}
return iterator;
}
linkedList* endList(){
if (iterator == NULL) return NULL;
while(iterator->next != NULL){
nextList();
}
return iterator;
}
linkedList** getIteratorList(){
return &iterator;
}
unsigned short int checkList(char* p_str){
if(iterator == NULL) return 0;
beginList();
for(int i = 0; i < sizeList(); i++){
if(strcmp(iterator->address, p_str) == 0){
return 1;
}else nextList();
}
beginList();
return 0;
}
client.h
#ifndef CLIENT_H_
#define CLIENT_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include "const.h"
#include "encrypt.h"
struct paramc{
struct sockaddr_in* server;
int* client_d;
};
volatile sig_atomic_t donec;
void client(char*);
void* receivec(void*);
void* sendc(void*);
void termc(int);
#endif
client.c
#include "client.h"
volatile sig_atomic_t donec = 0;
void client(char* address){
pthread_t r, s;
int client_d;
struct sockaddr_in server;
struct paramc args;
if((client_d = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
perror("\nsocket");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = inet_addr(address);
bzero(server.sin_zero, 8);
args.server = &server;
args.client_d = &client_d;
pthread_create(&r, NULL, receivec, (void*)&args);
pthread_create(&s, NULL, sendc, (void*)&args);
pthread_join(s, NULL);
}
void* receivec(void* data){
struct paramc* args = data;
struct sockaddr_in* server = args->server;
int* client_d = args->client_d;
unsigned int length = sizeof(struct sockaddr_in);
char buffer[BUFFER_MAX];
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = termc;
sigaction(SIGINT, &action, NULL);
while(!donec){
if(recvfrom(*client_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)server, &length) > 0){
decrypt(buffer);
printf("[%s]:%s", inet_ntoa(server->sin_addr), buffer);
bzero(buffer, BUFFER_MAX);
}
}
printf("Client terminated.\n");
return NULL;
}
void* sendc(void* data){
struct paramc* args = data;
struct sockaddr_in* server = args->server;
int* client_d = args->client_d;
char buffer[BUFFER_MAX];
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = termc;
sigaction(SIGINT, &action, NULL);
while(!donec){
bzero(buffer, BUFFER_MAX);
fgets(buffer, BUFFER_MAX - 1, stdin);
encrypt(buffer);
sendto(*client_d, buffer, BUFFER_MAX - 1, 0, (struct sockaddr*)server, sizeof(struct sockaddr_in));
}
printf("Client terminated.\n");
return NULL;
}
void termc(int signum){
donec = 1;
printf("\nTerminating client...\n");
}
const.h
#ifndef CONST_H_
#define CONST_H_
#define PORT 15151
#define BUFFER_MAX 1024
#endif
的main.c
#include "server.h"
#include "client.h"
//#define linkedlist_test
#ifdef linkedlist_test
#include "linkedList.h"
#endif
int main(int argc, char* argv[]){
#ifndef linkedlist_test
system("clear");
if(argc < 2){
server();
}else{
client(argv[1]);
}
#endif
#ifdef linkedlist_test
struct sockaddr_in test1;
test1.sin_family = AF_INET;
test1.sin_port = htons(PORT);
test1.sin_addr.s_addr = inet_addr("192.168.1.101");
bzero(test1.sin_zero, 8);
struct sockaddr_in test2;
test2.sin_family = AF_INET;
test2.sin_port = htons(PORT);
test2.sin_addr.s_addr = inet_addr("192.168.1.102");
bzero(test2.sin_zero, 8);
struct sockaddr_in test3;
test3.sin_family = AF_INET;
test3.sin_port = htons(PORT);
test3.sin_addr.s_addr = inet_addr("192.168.1.103");
bzero(test3.sin_zero, 8);
struct sockaddr_in test4;
test4.sin_family = AF_INET;
test4.sin_port = htons(PORT);
test4.sin_addr.s_addr = inet_addr("192.168.1.104");
bzero(test4.sin_zero, 8);
struct sockaddr_in test5;
test5.sin_family = AF_INET;
test5.sin_port = htons(PORT);
test5.sin_addr.s_addr = inet_addr("192.168.1.105");
bzero(test5.sin_zero, 8);
linkedList** iterator = getIteratorList();
printf("address: %p/%p\torder: %d\n", *iterator, addList(test1), sizeList());
printf("address: %p/%p\torder: %d\n", *iterator, addList(test2), sizeList());
printf("address: %p/%p\torder: %d\n", *iterator, addList(test3), sizeList());
printf("address: %p/%p\torder: %d\n", *iterator, addList(test4), sizeList());
printf("address: %p/%p\torder: %d\n", *iterator, addList(test5), sizeList());
printf("vypis testovych struktur priamo:\n%s\n", inet_ntoa(test1.sin_addr));
printf("%s\n", inet_ntoa(test2.sin_addr));
printf("%s\n", inet_ntoa(test3.sin_addr));
printf("%s\n", inet_ntoa(test4.sin_addr));
printf("%s\n", inet_ntoa(test5.sin_addr));
printf("========================\n");
checkList("192.168.1.104");
printf("checkList() test: adresa -//-.104 sa nachadza: %p, plna adresa je %s\n", (*iterator), (*iterator)->address);
beginList();
for(int i = 0; i < sizeList(); i++){
printf("[%p]list\'s output [%d]: %s\n", *iterator, i, (*iterator)->address);
nextList();
}
printf("========================\n");
removeList("192.168.1.102");
printf("deleting 192.168.1.102\n");
printf("size: %d\n", sizeList());
beginList();
for(int i = 0; i < sizeList(); i++){
printf("[%p]list\'s output [%d]: %s\n", *iterator, i, (*iterator)->address);
nextList();
}
printf("========================\n");
removeList("192.168.1.101");
printf("deleting 192.168.1.101\n");
printf("size: %d\n", sizeList());
beginList();
for(int i = 0; i < sizeList(); i++){
printf("[%p]list\'s output [%d]: %s\n", *iterator, i, (*iterator)->address);
nextList();
}
printf("========================\n");
removeList("192.168.1.105");
printf("deleting 192.168.1.105\n");
printf("size: %d\n", sizeList());
beginList();
for(int i = 0; i < sizeList(); i++){
printf("[%p]list\'s output [%d]: %s\n", *iterator, i, (*iterator)->address);
nextList();
}
printf("========================\n");
printf("removing the whole list\n");
if(clearList() == 0) printf("successfully removed\n"); else printf("some chiki-briki is not right. FAILUREEE!");
printf("size: %d\n", sizeList());
printf("========================\n");
#endif
return 0;
}
encrypt.c和encrypt.h只是两个函数char * encrypt(char *)和char * decrypt(char *),它们不对字符串做任何事情 - &gt; WIP