Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.98/40: Рейтинг темы: голосов - 40, средняя оценка - 4.98
Музыка нас Связала
 Аватар для Fonduee
232 / 232 / 52
Регистрация: 26.03.2008
Сообщений: 616

Чат (Сервер|Клиент) с UDP протоколом

27.12.2013, 17:30. Показов 7845. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем Привет,

вообщем задача написать простенький чат c использованием UDP протокола. Для начала я написал эхо-сервер (1 сервер - 1 клиент). Все работает на ура. Но 1 клиент для чата - это не дело. Нужно было как-то реализовать работу с n-Клиентами. Тут и "встал вопрос" - Как? UPD работает без сессий, а значит нельзя использовать "accept" и прочее, что можно с TCP. Значит так, как лучше всего запоминать пользователей? Лучше посылать простой текст на сервер или стуктуру (к примеру имя, сообщение, время, комманда)?

Мои наработки (пока 1x-1x):

server.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
 
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
 
/* SETTINGS */
 
#define MAX_CLIENTS 10
 
#define PORT 64546
#define BUFFLENGTH 256
 
#define WELCOME_MSG "Welcome, You have successfully connected to the server!"
 
typedef struct
{
  int active;
  unsigned short id, port;
  struct sockaddr_in data;
} member;
 
int main(int argc, char ** argv)
{
  char msg[BUFFLENGTH];
  socklen_t len;
 
  member members[MAX_CLIENTS];
 
  int sockfd, n;
  struct sockaddr_in server_addr, client_addr;
 
  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  {
    perror("An error occurred while creating socket");
    return EXIT_FAILURE;
  }
 
  memset(&server_addr, 0x00, sizeof(server_addr));
 
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  server_addr.sin_port = htons(PORT);
 
  if (bind(sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr)))
  {
    perror("An error occurred while binding socket");
    return EXIT_FAILURE;
  }
 
  for (;;)
  {
    len = sizeof(client_addr);
    n = recvfrom(sockfd, msg, BUFFLENGTH, 0, (struct sockaddr *) &client_addr, &len);
 
    msg[n] = 0;
 
    printf("Received (IP: %s:%d): %s", inet_ntoa(client_addr.sin_addr), (int) ntohs(client_addr.sin_port), msg);
 
    sendto(sockfd, msg, n, 0, (struct sockaddr *) &client_addr, sizeof(client_addr));
  }
 
  close(sockfd);
  return EXIT_SUCCESS;
}
client.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
 
/* SETTINGS */
 
#define MAX_CONNECTIONS 10
 
#define PORT 64546
#define BUFFLENGTH 256
 
#define LENGTH 20
 
int main(int argc, char ** argv)
{
  if (argc != 2)
  {
    printf("Usage: %s <ip> <port>\n", argv[0]);
    return EXIT_FAILURE;
  }
 
  char username[LENGTH];
 
  int sockfd, n;
  struct sockaddr_in server_addr, client_addr;
 
  char send[BUFFLENGTH];
  char recv[BUFFLENGTH];
 
  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  {
    perror("An error occurred while creating socket");
    return EXIT_FAILURE;
  }
 
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = inet_addr(argv[1]);
  server_addr.sin_port = htons(PORT);
 
  while (fgets(send, BUFFLENGTH, stdin) != NULL)
  {
    if (sendto(sockfd, send, strlen(send), 0, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1)
    {
 
    }
    n = recvfrom(sockfd, recv, BUFFLENGTH, 0, NULL, NULL);
    recv[n] = 0;
    fputs(recv, stdout);
  }
 
  return EXIT_SUCCESS;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.12.2013, 17:30
Ответы с готовыми решениями:

Низкоуровневые сокеты. Udp клиент-сервер
Здравствуйте.Помогите пожалуйста поправить код сервера,принимающего сообщение от клиента и выводящего его на экран.клиент компилируется,а...

Как объединить UDP клиент/сервер в одну программу?
Здравствуйте! Как объединить UDP клиент/сервер на С в одну программу? Есть ли у кого-нибудь готовый код?

Клиент-сервер udp: реализовать подключение множества клиентов
доброго времени суток. как реализовать подключение множества клиентов? понимаю, что необходимо организовать структуру сокетов, которые...

8
Псевдослучайный
1946 / 1146 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
27.12.2013, 18:45
Достаточно запомнить адреса, с которых приходят сообщения, client_addr то есть.
1
Музыка нас Связала
 Аватар для Fonduee
232 / 232 / 52
Регистрация: 26.03.2008
Сообщений: 616
27.12.2013, 20:03  [ТС]
А как на счет идеи, коннектится по TCP, а обмениваться данными|сообщениями по UDP, стоит оно того или из разряда тех еще велосипедов?
0
Z3JheSBoYXQ=
 Аватар для fanatdebian
342 / 237 / 83
Регистрация: 08.07.2012
Сообщений: 577
28.12.2013, 21:45
Цитата Сообщение от Fonduee Посмотреть сообщение
А как на счет идеи, коннектится по TCP, а обмениваться данными|сообщениями по UDP, стоит оно того или из разряда тех еще велосипедов?
Это избыточность. Это как при наличии брода через реку, переплывать ее на пароме. В двух местах все равно одновременно быть не сможешь. И да, не стоит в области, обсосанной кем только можно из авторов ( область tcp/ip ), изобретать велосипеды. Может стоит для начала ознакомиться с трудами Д. Камера "Разработка приложений типа клиент/сервер TCP/IP" там все разжевано, почему, зачем, и как.

Добавлено через 4 минуты
И да, я бы использовал не ip клиентов при udp, т.к. ip имеет нестабильное состояние при динамических адресах клиентуры или использования "прокладок" ( прокси и иже с ними ), а цеплять к пакетам уникальный ключ, по аналогии с ключами ssh, только проще.
1
 Аватар для 646kapeh064
59 / 58 / 16
Регистрация: 09.12.2013
Сообщений: 208
02.01.2014, 20:52
Цитата Сообщение от Fonduee Посмотреть сообщение
Нужно было как-то реализовать работу с n-Клиентами. Тут и "встал вопрос" - Как?
А почему нельзя в сообщении посылать идентификатор (IP, Mac... либо хеш суммы этих значения... да что угодно)?
0
Музыка нас Связала
 Аватар для Fonduee
232 / 232 / 52
Регистрация: 26.03.2008
Сообщений: 616
03.01.2014, 17:16  [ТС]
IP приходит и без моего участия через struct sockaddr_in, а здесь проблема была другого плана. Так как использовался UDP протокол, использование select() было не возможным, т.к. UDP соединения по типу "handshake" не устанавливает.

Сделал, как и посоветовали выше, сохранял sockaddr_in каждого клиента в хэш-таблицу и всё.
0
0 / 0 / 0
Регистрация: 04.01.2014
Сообщений: 2
05.01.2014, 00:05
Цитата Сообщение от Fonduee Посмотреть сообщение
IP приходит и без моего участия через struct sockaddr_in, а здесь проблема была другого плана. Так как использовался UDP протокол, использование select() было не возможным, т.к. UDP соединения по типу "handshake" не устанавливает.

Сделал, как и посоветовали выше, сохранял sockaddr_in каждого клиента в хэш-таблицу и всё.
Прошу прощения! Мог бы ты выложить сюда результат, который у тебя получился?
0
Музыка нас Связала
 Аватар для Fonduee
232 / 232 / 52
Регистрация: 26.03.2008
Сообщений: 616
05.01.2014, 00:15  [ТС]
Могу и выложить

Клиент (Чат)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
 
#include <netinet/in.h>
#include <arpa/inet.h>
 
#include <sys/types.h>
#include <sys/socket.h>
 
/* SETTINGS */
 
#define PORT 64546
#define BUFFLENGTH 256
 
#define LENGTH 20
 
int main(int argc, char ** argv)
{
  if (argc != 3)
  {
    printf("Usage: %s <ip> <username>\n", argv[0]);
    return EXIT_FAILURE;
  }
 
  char username[LENGTH];
  strcpy(username, argv[2]);
 
  int sockfd, n;
  struct sockaddr_in server_addr;
 
  char send[BUFFLENGTH];
  char recv[BUFFLENGTH];
 
  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  {
    perror("An error occurred while creating socket");
    return EXIT_FAILURE;
  }
 
  memset(&server_addr, 0, sizeof(server_addr));
 
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = inet_addr(argv[1]);
  server_addr.sin_port = htons(PORT);
 
  sendto(sockfd, username, LENGTH, 0, (struct sockaddr *) &server_addr, sizeof(server_addr));
 
  pid_t pid;
 
  if ((pid = fork()) < 0)
  {
    perror("An error occurred while forking");
    return EXIT_FAILURE;
  }
  else if (pid == 0)
  {
    for (;;)
    {
      n = recvfrom(sockfd, recv, BUFFLENGTH, 0, NULL, NULL);
      recv[n] = 0;
      fputs(recv, stdout);
    }
  }
  else
  {
    while (fgets(send, BUFFLENGTH, stdin) != NULL)
    {
      if (sendto(sockfd, send, strlen(send), 0, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1)
      {
        perror("An error occurred while sending message");
      }
    }
  }
 
  return EXIT_SUCCESS;
}
Сервер (Чат)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 201101L
#endif
 
#ifndef PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST_ENABLED 0
#endif
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
 
#include "chash.h"
 
#if PERFORMANCE_TEST_ENABLED
#include <time.h>
#endif
 
#include <netinet/in.h>
#include <arpa/inet.h>
 
#include <sys/types.h>
#include <sys/socket.h>
 
/* SETTINGS */
 
#define SERVERPORT 64546
#define BUFSIZE 256
 
#define WELCOME "Welcome, You have successfully connected to the server!\n"
 
typedef struct client
{
  char nickname[20];
  struct sockaddr_in data;
} client_t;
 
char * s_addr_to_string(struct sockaddr_in *address);
unsigned long hash(const void * value);
int compare(const void * x, const void * y);
 
char * s_addr_to_string(struct sockaddr_in *address)
{
  char *s = (char *) calloc(24, sizeof(char));
  sprintf(s, "%s:%d", inet_ntoa((*address).sin_addr), (int) ntohs((*address).sin_port));
  return s;
}
 
unsigned long hash(const void * value)
{
  unsigned long hash = 49613;
  int c;
  while ((c = *(char *) value++))
  {
    hash = ((hash << 5) + hash) + c;
  }
  return hash;
}
 
void printroom(void *key, void *value, void *state)
{
  printf("table[\"%s\"] = \"%d\"\n", (char *) key, value == NULL);
}
 
int compare(const void * x, const void * y)
{
  return strcmp((const char *) x, (const char *) y);
}
 
int main(int argc, char ** argv)
{
  printf("-------------------------------------------------------\n");
  printf("# Projekt: Chat mit Hut\n\n");
  printf("# B-BKSPP-PR\n");
  printf("# Authors: Nikolaj S. & Rafael F.\n\n");
 
  printf("# Datum: 22-12-2013\n\n");
 
  printf("# SDL 2.0.1 http://www.libsdl.org/download-2.0.php\n");
  printf("# CMAKE 2.8 http://www.cmake.org/cmake/resources/software.html\n");
  printf("-------------------------------------------------------\n");
 
  socklen_t socklen = sizeof(struct sockaddr_in);
 
#if PERFORMANCE_TEST_ENABLED
  struct timespec start, finish;
#endif
 
  char buffer[BUFSIZE];
 
  int sockfd, recvlen;
  void **s;
  struct sockaddr_in server_addr, client_addr;
 
  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  {
    perror("An error occurred while creating socket");
    return EXIT_FAILURE;
  }
 
  memset((void *) &server_addr, 0, (size_t) socklen);
 
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  server_addr.sin_port = htons(SERVERPORT);
 
  if (bind(sockfd, (struct sockaddr *) &server_addr, socklen))
  {
    perror("An error occurred while binding socket");
    return EXIT_FAILURE;
  }
 
  hashtable_t *ht = hashtable_alloc(&hash, &compare, 0);
  char * key; //TODO: Don't forget to free!
  for (;;)
  {
#if PERFORMANCE_TEST_ENABLED
    clock_gettime(CLOCK_MONOTONIC, &start);
#endif
 
    if ((recvlen = recvfrom(sockfd, buffer, BUFSIZE, 0, (struct sockaddr *) &client_addr, &socklen)) > 0)
    {
      if ((s = hashtable_access(ht, key = s_addr_to_string(&client_addr), NULL)) == NULL)
      {
        client_t *cl = (client_t *) malloc(sizeof(client_t));
        (*cl).data = client_addr;
        strcpy((*cl).nickname, buffer);
 
        printf("%s (%s:%d) connected\n", (*cl).nickname, inet_ntoa((*cl).data.sin_addr), (int) ntohs((*cl).data.sin_port));
 
        if (sendto(sockfd, WELCOME, sizeof(WELCOME), 0, (struct sockaddr *) &(*cl).data, socklen) == -1)
        {
          perror("An error occurred while sending welcome message");
        }
        hashtable_access(ht, (void *) key, (void *) cl);
      }
      else
      {
        int outlen = recvlen + strlen((*(client_t *) (*s)).nickname) + 2;
        char * temp = calloc(outlen, sizeof(char));
 
        buffer[recvlen] = 0;
 
        sprintf(temp, "%s: %s", (*(client_t *) (*s)).nickname, buffer);
        printf("%s", temp);
 
        for (int i = 0; i < ht->size; i++)
        {
          if ((ht->buckets[i].key) != NULL)
          {
            sendto(sockfd, temp, outlen, 0, (struct sockaddr *) &(*(client_t*) ht->buckets[i].value).data, socklen);
          }
        }
        free(temp);
      }
    }
#if PERFORMANCE_TEST_ENABLED
    clock_gettime(CLOCK_MONOTONIC, &finish);
    printf("Executed in : %ld ns\n", (finish.tv_sec - start.tv_sec) * (1000000000l) + (finish.tv_nsec - start.tv_nsec));
#endif
  }
  hashtable_free(ht, &free, &free);
  close(sockfd);
  return EXIT_SUCCESS;
}
1
0 / 0 / 0
Регистрация: 04.01.2014
Сообщений: 2
05.01.2014, 13:32
Цитата Сообщение от Fonduee Посмотреть сообщение
Могу и выложить

Клиент (Чат)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
 
#include <netinet/in.h>
#include <arpa/inet.h>
 
#include <sys/types.h>
#include <sys/socket.h>
 
/* SETTINGS */
 
#define PORT 64546
#define BUFFLENGTH 256
 
#define LENGTH 20
 
int main(int argc, char ** argv)
{
  if (argc != 3)
  {
    printf("Usage: %s <ip> <username>\n", argv[0]);
    return EXIT_FAILURE;
  }
 
  char username[LENGTH];
  strcpy(username, argv[2]);
 
  int sockfd, n;
  struct sockaddr_in server_addr;
 
  char send[BUFFLENGTH];
  char recv[BUFFLENGTH];
 
  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  {
    perror("An error occurred while creating socket");
    return EXIT_FAILURE;
  }
 
  memset(&server_addr, 0, sizeof(server_addr));
 
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = inet_addr(argv[1]);
  server_addr.sin_port = htons(PORT);
 
  sendto(sockfd, username, LENGTH, 0, (struct sockaddr *) &server_addr, sizeof(server_addr));
 
  pid_t pid;
 
  if ((pid = fork()) < 0)
  {
    perror("An error occurred while forking");
    return EXIT_FAILURE;
  }
  else if (pid == 0)
  {
    for (;;)
    {
      n = recvfrom(sockfd, recv, BUFFLENGTH, 0, NULL, NULL);
      recv[n] = 0;
      fputs(recv, stdout);
    }
  }
  else
  {
    while (fgets(send, BUFFLENGTH, stdin) != NULL)
    {
      if (sendto(sockfd, send, strlen(send), 0, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1)
      {
        perror("An error occurred while sending message");
      }
    }
  }
 
  return EXIT_SUCCESS;
}
Сервер (Чат)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 201101L
#endif
 
#ifndef PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST_ENABLED 0
#endif
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
 
#include "chash.h"
 
#if PERFORMANCE_TEST_ENABLED
#include <time.h>
#endif
 
#include <netinet/in.h>
#include <arpa/inet.h>
 
#include <sys/types.h>
#include <sys/socket.h>
 
/* SETTINGS */
 
#define SERVERPORT 64546
#define BUFSIZE 256
 
#define WELCOME "Welcome, You have successfully connected to the server!\n"
 
typedef struct client
{
  char nickname[20];
  struct sockaddr_in data;
} client_t;
 
char * s_addr_to_string(struct sockaddr_in *address);
unsigned long hash(const void * value);
int compare(const void * x, const void * y);
 
char * s_addr_to_string(struct sockaddr_in *address)
{
  char *s = (char *) calloc(24, sizeof(char));
  sprintf(s, "%s:%d", inet_ntoa((*address).sin_addr), (int) ntohs((*address).sin_port));
  return s;
}
 
unsigned long hash(const void * value)
{
  unsigned long hash = 49613;
  int c;
  while ((c = *(char *) value++))
  {
    hash = ((hash << 5) + hash) + c;
  }
  return hash;
}
 
void printroom(void *key, void *value, void *state)
{
  printf("table[\"%s\"] = \"%d\"\n", (char *) key, value == NULL);
}
 
int compare(const void * x, const void * y)
{
  return strcmp((const char *) x, (const char *) y);
}
 
int main(int argc, char ** argv)
{
  printf("-------------------------------------------------------\n");
  printf("# Projekt: Chat mit Hut\n\n");
  printf("# B-BKSPP-PR\n");
  printf("# Authors: Nikolaj S. & Rafael F.\n\n");
 
  printf("# Datum: 22-12-2013\n\n");
 
  printf("# SDL 2.0.1 http://www.libsdl.org/download-2.0.php\n");
  printf("# CMAKE 2.8 http://www.cmake.org/cmake/resources/software.html\n");
  printf("-------------------------------------------------------\n");
 
  socklen_t socklen = sizeof(struct sockaddr_in);
 
#if PERFORMANCE_TEST_ENABLED
  struct timespec start, finish;
#endif
 
  char buffer[BUFSIZE];
 
  int sockfd, recvlen;
  void **s;
  struct sockaddr_in server_addr, client_addr;
 
  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  {
    perror("An error occurred while creating socket");
    return EXIT_FAILURE;
  }
 
  memset((void *) &server_addr, 0, (size_t) socklen);
 
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  server_addr.sin_port = htons(SERVERPORT);
 
  if (bind(sockfd, (struct sockaddr *) &server_addr, socklen))
  {
    perror("An error occurred while binding socket");
    return EXIT_FAILURE;
  }
 
  hashtable_t *ht = hashtable_alloc(&hash, &compare, 0);
  char * key; //TODO: Don't forget to free!
  for (;;)
  {
#if PERFORMANCE_TEST_ENABLED
    clock_gettime(CLOCK_MONOTONIC, &start);
#endif
 
    if ((recvlen = recvfrom(sockfd, buffer, BUFSIZE, 0, (struct sockaddr *) &client_addr, &socklen)) > 0)
    {
      if ((s = hashtable_access(ht, key = s_addr_to_string(&client_addr), NULL)) == NULL)
      {
        client_t *cl = (client_t *) malloc(sizeof(client_t));
        (*cl).data = client_addr;
        strcpy((*cl).nickname, buffer);
 
        printf("%s (%s:%d) connected\n", (*cl).nickname, inet_ntoa((*cl).data.sin_addr), (int) ntohs((*cl).data.sin_port));
 
        if (sendto(sockfd, WELCOME, sizeof(WELCOME), 0, (struct sockaddr *) &(*cl).data, socklen) == -1)
        {
          perror("An error occurred while sending welcome message");
        }
        hashtable_access(ht, (void *) key, (void *) cl);
      }
      else
      {
        int outlen = recvlen + strlen((*(client_t *) (*s)).nickname) + 2;
        char * temp = calloc(outlen, sizeof(char));
 
        buffer[recvlen] = 0;
 
        sprintf(temp, "%s: %s", (*(client_t *) (*s)).nickname, buffer);
        printf("%s", temp);
 
        for (int i = 0; i < ht->size; i++)
        {
          if ((ht->buckets[i].key) != NULL)
          {
            sendto(sockfd, temp, outlen, 0, (struct sockaddr *) &(*(client_t*) ht->buckets[i].value).data, socklen);
          }
        }
        free(temp);
      }
    }
#if PERFORMANCE_TEST_ENABLED
    clock_gettime(CLOCK_MONOTONIC, &finish);
    printf("Executed in : %ld ns\n", (finish.tv_sec - start.tv_sec) * (1000000000l) + (finish.tv_nsec - start.tv_nsec));
#endif
  }
  hashtable_free(ht, &free, &free);
  close(sockfd);
  return EXIT_SUCCESS;
}
Спасибо тебе огромное!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.01.2014, 13:32
Помогаю со студенческими работами здесь

Клиент-сервер со своим протоколом передачи данных
На должность Junior .Net прислали задание: Необходимо разработать клиент-серверное приложение на C#, обменивающееся сообщениями по...

UDP клиент сервер
Помогите пожалуйста сделать &quot;Получение по запросу имени компьютера, физического адреса, IP-адреса.&quot; Есть такое, но оно выводит в...

UDP Клиент-Сервер
На этот раз мне надо реализовать клиент-серверное приложение использую UDP. В интернете прочитал, простой Эхо сервер сделал. А вот дальше...

UDP Клиент Сервер
Есть простой UDP клиент и UDP эхо-сервер. Вот исходники: Сервер: #include &quot;stdafx.h&quot; #pragma comment ( lib,...

UDP Клиент-Сервер
Здравствуйте! Написала два приложения: клиент и сервер. Обработала, чтобы клиент мог отправлять данные несколько раз. Вопрос: как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита табличной части. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru