makefile:
- jchat: main.o login.o regist.o tcp.o
- gcc -w main.o login.o regist.o tcp.o -o jchat
- rm -f *.o *.gch *~
- main.o: main.c login.h regist.h tcp.h
- gcc -w -c main.c login.h regist.h tcp.h
- login.o: login.c login.h tcp.h
- gcc -w -c login.c login.h tcp.h
- regist.o: regist.c regist.h tcp.h
- gcc -w -c regist.c regist.h tcp.h
- tcp.o: tcp.c tcp.h
- gcc -w -c tcp.c tcp.h
- clean:
- rm -f *.o *.gch *~ jchat
main.c:
- /*client/main.c*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include "login.h"
- #include "regist.h"
- #include "tcp.h"
- #define MAXLINE 4096
- #define IP "127.0.0.1" // localhost
- #define PORT 12345
- char sendbuff[MAXLINE], recvbuff[MAXLINE];//send buffer & recv buffer
- int sockfd;//socket file descriptor
- int main(int argc, char *argv[])
- {
- ) {
- exit();
- }
- ];
- ) {
- printf("login or regist:");
- scanf("%s", choice);
- ) {
- login(sockfd);
- }
- ) {
- regist(sockfd);
- }
- else {
- puts("input login or regist!");
- }
- }
- }
login.c:登入操作
- /*client/login.c*/
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include "login.h"
- #include "tcp.h"
- #define MAXLINE 4096
- #define IP "127.0.0.1" // localhost
- #define PORT 12345
- ], passwd[];
- ];
- /*
- * login to server
- * return 1 if succeed, 0 if fail
- */
- int login_succeed(int sockfd)
- {
- char sendbuff[MAXLINE], recvbuff[MAXLINE];
- sprintf(sendbuff, "l:%s:%s", user, passwd);
- write(sockfd, sendbuff, strlen(sendbuff));
- //printf("sendbuff> '%s'\n", sendbuff);
- int n = read(sockfd, recvbuff, MAXLINE);
- recvbuff[n] = '\0';
- //printf("recvbuff> '%s'\n", recvbuff);
- ) ;
- ;
- }
- /*
- * send message to another user by server
- */
- void send_mesg(int sockfd)
- {
- char sendbuff[MAXLINE];
- int len = strlen(line);
- , j, k, pos;
- while (i<len && (line[i]==' ' || line[i]=='\t')) ++i;
- j = i + ;
- while (j<len && line[j]!=' ' && line[j]!='\t') ++j;
- k = j + ;
- while (k<len && (line[k]==' ' || line[k]=='\t')) ++k;
- , ulen = strlen(user);
- sendbuff[] = ] = ':';
- ; pos<ulen; ++pos) sendbuff[send_len++] = user[pos];
- sendbuff[send_len++] = ':';
- for (pos=i; pos<j; ++pos) sendbuff[send_len++] = line[pos];
- sendbuff[send_len++] = ':';
- for (pos=k; pos<len; ++pos) sendbuff[send_len++] = line[pos];
- sendbuff[send_len++] = '\0';
- write(sockfd, sendbuff, strlen(sendbuff));
- //printf("send_mesg sendbuff> '%s'\n", sendbuff);
- }
- /*
- * ask the server the online user
- */
- void check_online(int sockfd)
- {
- char sendbuff[MAXLINE], recvbuff[MAXLINE];
- sprintf(sendbuff, "o");
- write(sockfd, sendbuff, strlen(sendbuff));
- //printf("check_online sendbuff> '%s'\n", sendbuff);
- int recv_len = read(sockfd, recvbuff, MAXLINE);
- recvbuff[recv_len] = '\0';
- //printf("check_online recvbuff> '%s'\n", recvbuff);
- ) {
- printf("no one online\n");
- }
- else {
- , j, k, num = ;
- ][];
- while (i < recv_len) {
- j = i+;
- while (recvbuff[j] != ';') ++j;
- for (k=i; k<j; ++k) on[num][k-i] = recvbuff[k];
- on[num][j-i] = '\0';
- ++num;
- i = j + ;
- }
- printf("%d online user:\n", num);
- ; k<num; ++k) printf(" %s\n", on[k]);
- }
- }
- /*
- * quit this client
- * quit the process fork by server
- */
- void quit(int sockfd)
- {
- char sendbuff[MAXLINE];
- sprintf(sendbuff, "q:%s", user);
- write(sockfd, sendbuff, strlen(sendbuff));
- //printf("quit sendbuff> '%s'\n", sendbuff);
- }
- /*
- * get unread message from server every 1 second
- */
- void get_mesg(int sockfd)
- {
- char sendbuff[MAXLINE], recvbuff[MAXLINE];
- ) {
- sleep();
- sprintf(sendbuff, "g:%s", user);
- write(sockfd, sendbuff, strlen(sendbuff));
- //printf("get_mesg sendbuff> '%s'\n", sendbuff);
- int recv_len = read(sockfd, recvbuff, MAXLINE);
- recvbuff[recv_len] = '\0';
- //printf("get_mesg recvbuff> '%s'\n", recvbuff);
- ) { // no message get
- continue;
- }
- int num, i, j, k, l;
- num = i = ;
- ][];
- while (i < recv_len) {
- j = i + ;
- while (recvbuff[j] != ';') ++j;
- k = i;
- while (k<j && recvbuff[k]!=':') ++k;
- ;
- for (l=i; l<k; ++l) line[line_len++] = recvbuff[l];
- line[line_len++] = ':';line[line_len++] = ' ';
- ; l<j; ++l) line[line_len++] = recvbuff[l];
- line[line_len] = '\0';
- puts(line);
- i = j + ;
- }
- }
- }
- /*
- * send online notice to server every 5 seconds
- */
- void online_notice(int sockfd)
- {
- char sendbuff[MAXLINE];
- ) {
- sprintf(sendbuff, "a:%s", user);
- write(sockfd, sendbuff, strlen(sendbuff));
- //printf("sendbuff> '%s'\n", sendbuff);
- sleep();
- }
- }
- /*
- * everything after login
- * thread 1 : receive user command
- * thread 2 : get unread message from server
- * thread 3 : send online notice to server
- */
- void login(int sockfd)
- {
- printf("user: ");
- scanf("%s", user);
- printf("password: ");
- scanf("%s", passwd);
- if (login_succeed(sockfd)) {
- printf("welcome %s~\n", user);
- pid_t pid1 = fork();
- ) {
- pid_t pid2 = fork();
- ) { // thread 1 : input command
- while (gets(line)) {
- ]) {
- case 's': // send message
- send_mesg(sockfd);
- break;
- case 'o': // check online
- check_online(sockfd);
- break;
- case 'q': // quit
- quit(sockfd);
- kill(pid1, );
- kill(pid2, );
- printf("goobye %s ~\n", user);
- exit();
- break;
- }
- }
- }
- else { // thread 2 : get message from server
- get_mesg(sockfd);
- }
- }
- else { // thread 3 : send online notice
- online_notice(sockfd);
- }
- }
- else {
- printf("login failed\n");
- }
- }
login.h:
- /*client/login.h*/
- #ifndef LOGIN_H
- #define LOGIN_H
- void login(int sockfd);
- #endif // LOGIN_H
regist.c:註冊操作
- /*client/regist.c*/
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include "regist.h"
- #include "tcp.h"
- #define MAXLINE 4096
- extern char sendbuff[MAXLINE], recvbuff[MAXLINE];
- ], passwd[];
- /*
- * regist new user
- * return 1 if succeed, 0 if fail
- */
- int regist_succeed(int sockfd)
- {
- sprintf(sendbuff, "r:%s:%s", user, passwd);
- write(sockfd, sendbuff, strlen(sendbuff));
- int n = read(sockfd, recvbuff, MAXLINE);
- recvbuff[n] = ;
- ) ;
- ;
- }
- /*
- * regist
- */
- void regist(int sockfd)
- {
- printf("user: ");
- scanf("%s", user);
- printf("password: ");
- scanf("%s", passwd);
- if (regist_succeed(sockfd)) {
- printf("regist a new user!\n");
- }
- else {
- printf("fail in regist new user!\n");
- }
- }
regist.h:
- /*client/regist.h*/
- #ifndef REGIST_H
- #define REGIST_H
- void regist(int sockfd);
- #endif // REGIST_H
tcp.c:建立與伺服器的連線
- /*client/tcp.c*/
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <netinet/in.h>
- #include "tcp.h"
- /*
- * link to assign IP and port
- * return the socket file descriptor
- */
- int link_server(char *IP, int port)
- {
- int sockfd;
- struct sockaddr_in servaddr;
- )) < ) {
- fprintf(stderr, "socket error\n");
- ;
- }
- memset(&servaddr, , sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(port);
- ) {
- fprintf(stderr, "inet_pton error for %s\n", IP);
- ;
- }
- ) {
- fprintf(stderr, "connect error\n");
- ;
- }
- return sockfd;
- }
tcp.h:
- /*client/tcp.h*/
- #ifndef TCP_H
- #define TCP_H
- /*
- * link IP:port using tcp
- * return sock file descriptor of the link (-1 if error)
- */
- int link_server(char *IP, int port);
- #endif // TCP_H