-
Notifications
You must be signed in to change notification settings - Fork 2
/
client.c
161 lines (146 loc) · 3.62 KB
/
client.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
#include "client.h"
#include "net.h"
#include "user.h"
#include "message.h"
#include "ui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <ncurses/ncurses.h>
#define PORT "9034"
#define CON_LEN 250 /* content length, where content is what the user types */
#define VAL_LEN 15
#define SUB_LEN 7
#define PAD_LEN 2 /* for '!'/'@' and ':' */
#define USR_MSG_LEN (CON_LEN + PAD_LEN + VAL_LEN) /*length of user messages */
#define CLI_MSG_LEN (SUB_LEN + PAD_LEN + VAL_LEN) /* length of client messages */
char name[VAL_LEN];
unsigned short flag = 1;
WINDOW *main_win, *msg_win, *msg_win_box, *ip_win, *ip_win_box, *login_win;
void login_form()
{
char *login_prompt = "Enter preferred alias: ";
wprintw(ip_win, login_prompt);
wmove(ip_win, 0, strlen(login_prompt));
wrefresh(ip_win);
get_ip(name, VAL_LEN);
wclear(ip_win);
wrefresh(ip_win);
}
void login(const int sockfd)
{
bzero(name, strlen(name));
char res[VAL_LEN], msg[CLI_MSG_LEN];
int flag = 1;
char res_msg[CON_LEN];
while (flag) {
login_form(name);
trim_str(name);
pack_client_msg(msg, name, CNAME);
if (send(sockfd, msg, strlen(msg), 0) == -1) {
perror("send");
exit(1);
}
bzero(msg, CLI_MSG_LEN);
if (recv(sockfd, msg, CLI_MSG_LEN, 0) == -1) {
perror("recv");
exit(1);
}
unpack_client_msg(msg, res);
if (!strcmp(res, "exists\n"))
strcpy(res_msg, "Sorry, the alias is taken. Please choose another.");
else if (!strcmp(res, "long\n"))
strcpy(res_msg, "This alias is too long. Choose a shorter one.");
else
flag = 0;
mvwaddstr(msg_win, 0, 0, res_msg);
wrefresh(msg_win);
}
strcpy(res_msg, "The name has been assigned. Press a key to enter chat.");
mvwaddstr(msg_win, 0, 0, res_msg);
wrefresh(msg_win);
getch();
wclear(msg_win);
wrefresh(msg_win);
}
void thread_send(void *sfd)
{
int sockfd = *((int*)sfd);
char buf[CON_LEN], msg[USR_MSG_LEN];
wmove(ip_win, 0, 0);
wrefresh(ip_win);
while (1) {
get_ip(buf, CON_LEN);
if (!strcmp(buf, "quit()")) {
endwin();
exit(1);
}
pack_usr_msg(msg, buf, name);
if (send(sockfd, msg, strlen(msg), 0) == -1) {
endwin();
perror("send");
exit(1);
}
print_msg(name, buf);
bzero(buf, CON_LEN);
bzero(msg, USR_MSG_LEN);
wmove(ip_win, 0, 0);
wclear(ip_win);
wrefresh(ip_win);
}
}
void thread_recv(void *sfd)
{
int sockfd = *((int*)sfd);
char buf[USR_MSG_LEN], msg[USR_MSG_LEN];
char sender_name[VAL_LEN];
while (1) {
if (recv(sockfd, msg, USR_MSG_LEN, 0) == -1) {
endwin();
perror("recv");
exit(1);
}
unpack_usr_msg(msg, buf, sender_name);
print_msg(sender_name, buf);
bzero(buf, strlen(buf));
bzero(msg, USR_MSG_LEN);
}
}
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "There must be 2 arguments (only)\n");
exit(1);
}
init_ui();
struct addrinfo *list = init_addrinfos(-1, AF_UNSPEC, SOCK_STREAM, argv[1], PORT);
int sockfd;
struct addrinfo *addr = bind_socket(list, &sockfd, 0);
if (sockfd == -1)
init_err_scr(sockfd, "Connection Failed", "No valid addrinfo struct", 1);
else if (!addr)
init_err_scr(1, "Connection Failed", "Socket could not connect to server", 1);
login(sockfd);
pthread_t t_send, t_recv;
if (pthread_create(&t_send, NULL, (void *)thread_send, (void*)&sockfd)) {
endwin();
fprintf(stderr, "Cannot create the send thread.\n");
return 1;
}
if (pthread_create(&t_recv, NULL, (void *)thread_recv, (void*)&sockfd)) {
endwin();
fprintf(stderr, "Cannot create the recv thread.\n");
return 1;
}
while (1)
if (!flag)
endwin();
close(sockfd);
return 0;
}