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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
| #include <stdlib.h>
#include <stdio.h>
#include <linux/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
typedef struct hostent hostent;
typedef struct servent servent;
char *msgs; // Pour stocker l'historique des messages
GtkWidget* entry;
pthread_t threadReception;
int socket_descriptor;
GtkWidget* label;
GtkWidget* scrollbar;
GtkAdjustment* vadjustment;
/* Réception des messages */
void* reception (void* donnee) {
int longueur;
int connecte = 1;
char buffer[1024];
gdouble upper;
while (1) {
if ((longueur = read(socket_descriptor, buffer, sizeof(buffer))) > 0) {
printf("Message destinataire : \n");
write(1, buffer, longueur);
msgs = realloc(msgs, sizeof(char)*sizeof(buffer)*sizeof(msgs));
strcat(msgs, buffer);
gtk_label_set_text(GTK_LABEL(label), msgs);
gtk_misc_set_alignment(GTK_MISC(label), 0, 1);
// Ajustement de la scrollbar
vadjustment = gtk_scrolled_window_get_vadjustment((GTK_SCROLLED_WINDOW(scrollbar)));
upper = gtk_adjustment_get_upper(vadjustment);
gtk_adjustment_set_value(vadjustment,upper);
printf("\n Fin de la reception. \n");
}
}
}
void envoi (GtkWidget *widget, GtkWidget *view) {
GtkTextBuffer* text_buffer = 0;
GtkTextIter start;
GtkTextIter end;
gchar* buf = 0;
gdouble upper;
char msgsend[1024] = "";
char msgrecv[1024];
int longueur; // longueur d'un buffer utilise
printf("Envoi d'un message au serveur. \n");
// On récupère le buffer
text_buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
// On récupère l'origine du buffer
gtk_text_buffer_get_start_iter(text_buffer, &start);
// On récupère la fin du buffer
gtk_text_buffer_get_end_iter(text_buffer, &end);
// On copie le contenu du buffer dans une variable
buf = gtk_text_buffer_get_text(text_buffer, &start, &end,TRUE);
strcat(msgsend,buf);
// Mise en attente du programme pour simuler un délai de transmission
sleep(1);
printf("Message envoye : %s \n", msgsend);
// Envoi du message vers le serveur
if ((write(socket_descriptor, msgsend, strlen(msgsend))) < 0) {
perror("Erreur : impossible d'ecrire le message destine au serveur");
exit(1);
}
// Lecture de la réponse en provenance du serveur
if ((longueur = read(socket_descriptor, msgrecv, sizeof(msgrecv))) > 0) {
printf("Reponse du serveur : \n");
write(1, msgrecv, longueur);
msgs = realloc(msgs, sizeof(char)*sizeof(msgrecv)*sizeof(msgs));
strcat(msgs, msgrecv);
gtk_label_set_text(GTK_LABEL(label), msgs);
// Ajustement de la scrollbar du label
vadjustment = gtk_scrolled_window_get_vadjustment((GTK_SCROLLED_WINDOW(scrollbar)));
upper = gtk_adjustment_get_upper(vadjustment);
gtk_adjustment_set_value(vadjustment, upper);
}
printf("Fin de la reception. \n");
gtk_text_buffer_get_bounds(text_buffer, &start, &end);
gtk_text_buffer_delete(text_buffer, &start, &end);
g_free(buf);
}
/* Envoie un message en appuyant sur la touche Enter */
gboolean on_key_press (GtkWidget* widget, GdkEventKey* event, GtkWidget* view) {
if (event->keyval == GDK_Return) {
envoi(widget, view);
}
return 0;
}
void connexion (GtkWidget *widget, GtkWidget* window) {
sockaddr_in adresse_locale; // adresse de socket local
hostent* ptr_host; // info sur une machine hote
servent* ptr_service; // info sur service
char* host = "127.0.0.1";
int longueur;
GtkWidget* box;
GtkWidget* text_view;
GtkWidget* button;
GtkWidget* scrollbar2;
GtkWidget* menuBar;
GtkWidget* menu;
GtkWidget* menuItem;
gchar* sUtf8;
printf("Adresse du serveur : %s \n", host);
if ((ptr_host = gethostbyname(host)) == NULL) {
perror("Erreur : impossible de trouver le serveur a partir de son adresse");
exit(1);
}
// Copie caractère par caractère des infos de ptr_host vers adresse_locale
bcopy((char*)ptr_host->h_addr, (char*)&adresse_locale.sin_addr, ptr_host->h_length);
adresse_locale.sin_family = AF_INET;
// Utiliser un nouveau numéro de port
adresse_locale.sin_port = htons(5254);
printf("Numero de port pour la connexion au serveur : %d \n", ntohs(adresse_locale.sin_port));
// Création de la socket
if ((socket_descriptor = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Erreur : impossible de creer la socket de connexion avec le serveur");
exit(1);
}
// Tentative de connexion au serveur dont les infos sont dans adresse_locale
if ((connect(socket_descriptor, (sockaddr*)(&adresse_locale), sizeof(adresse_locale))) < 0) {
perror("Erreur : impossible de se connecter au serveur");
exit(1);
}
printf("Connexion etablie avec le serveur. \n");
const gchar* pseudo = gtk_entry_get_text(GTK_ENTRY(entry));
write(socket_descriptor, pseudo, strlen(pseudo)); // On envoie le pseudo au serveur
vadjustment = NULL;
msgs = malloc(sizeof(char));
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
gtk_window_set_title(GTK_WINDOW(window), "Tchat");
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), 0);
box=gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(window), box);
/* Création du menu */
menuBar = gtk_menu_bar_new();
menu = gtk_menu_new();
/* Se connecter */
menuItem = gtk_menu_item_new_with_label("Se connecter");
gtk_menu_append(GTK_MENU(menu), menuItem);
gtk_signal_connect_object(GTK_OBJECT(menuItem), "activate", GTK_SIGNAL_FUNC(envoi), NULL); // A modifier
/* Menu fichier */
menuItem = gtk_menu_item_new_with_label("Fichier");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuItem), menu);
gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), menuItem);
gtk_box_pack_start(GTK_BOX(box), menuBar, FALSE, FALSE, 0);
/* Scrollbar pour le label */
scrollbar = gtk_scrolled_window_new(NULL, vadjustment);
gtk_box_pack_start(GTK_BOX(box), scrollbar, TRUE, TRUE, 5);
/* Création du label */
sUtf8 = g_locale_to_utf8("", -1, NULL, NULL, NULL);
label = gtk_label_new(sUtf8);
g_free(sUtf8);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); // Saut de ligne automatique (seulement visuel)
gtk_misc_set_alignment(GTK_MISC(label), 0, 1); // Texte placé en bas à gauche
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollbar), label);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbar), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
/* Scrollbar pour le text_view */
scrollbar2 = gtk_scrolled_window_new(NULL, NULL);
gtk_box_pack_start(GTK_BOX(box), scrollbar2, TRUE, TRUE, 5);
/* Création du text_view */
text_view = gtk_text_view_new();
gtk_container_add(GTK_CONTAINER(scrollbar2), text_view);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view), GTK_WRAP_CHAR); // Saut de ligne automatique (seulement visuel)
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbar2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
/* Création du bouton Envoyer */
button = gtk_button_new_with_label("Envoyer");
gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,0);
g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(on_key_press), (gpointer) text_view);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(envoi), (gpointer) text_view);
gtk_widget_show_all(window);
gtk_main();
// Le thread qui va recevoir les données du serveur
pthread_create(&threadReception, NULL, reception, NULL);
free(msgs);
}
int main (int argc, char* argv[]) {
GtkWidget* window;
GtkWidget* box;
GtkWidget* labelpseudo;
GtkWidget* button;
gchar* sUtf8;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
gtk_window_set_title(GTK_WINDOW(window), "Tchat");
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), 0);
box=gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(window), box);
/* Création du label */
sUtf8 = g_locale_to_utf8("Pseudo : ", -1, NULL, NULL, NULL);
labelpseudo = gtk_label_new(sUtf8);
g_free(sUtf8);
gtk_misc_set_alignment(GTK_MISC(labelpseudo), 0, 1); // Texte placé en bas à gauche
gtk_box_pack_start(GTK_BOX(box), labelpseudo, TRUE, TRUE, 5);
/* Création de l'entry */
entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 5);
/* Création du bouton Se connecter */
button = gtk_button_new_with_label("Se connecter");
gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,0);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(connexion), (gpointer) window);
gtk_widget_show_all(window);
gtk_main();
return 0;
} |
Partager