jchat:linux聊天程序4:客户端
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
jchat:linux聊天程序4:客户端的更多相关文章
- jchat:linux聊天程序1:简介
做一个linux的聊天软件,虽然没什么创意,但是它可以用来锻炼和测试我对网络编程的掌握程度,也借此机会做一些有意思的程序. 这里做的是linux下一个命令行的客户端与服务器的聊天程序,没写界面,因为对 ...
- jchat:linux聊天程序3:服务器
makefile: jchat_server: main.o process.o sql.o gcc -o jchat_server main.o process.o sql.o -L/usr/lib ...
- jchat:linux聊天程序2:MySQL
该软件使用的数据库为MySQL,因为它免费.开源,在linux下几乎就是最好的选择. 首先要在mysql中root用户新建数据库并赋权给本用户: create database jchat; gran ...
- boost asio异步读写网络聊天程序客户端 实例详解
boost官方文档中聊天程序实例讲解 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...
- Socket聊天程序——Common
写在前面: 上一篇记录了Socket聊天程序的客户端设计,为了记录的完整性,这里还是将Socket聊天的最后一个模块--Common模块记录一下.Common的设计如下: 功能说明: Common模块 ...
- Socket编程实践(3) 多连接服务器实现与简单P2P聊天程序例程
SO_REUSEADDR选项 在上一篇文章的最后我们贴出了一个简单的C/S通信的例程.在该例程序中,使用"Ctrl+c"结束通信后,服务器是无法立即重启的,如果尝试重启服务器,将被 ...
- 网络编程应用:基于TCP协议【实现一个聊天程序】
要求: 基于TCP协议实现一个聊天程序,客户端发送一条数据,服务器端发送一条数据 客户端代码: package Homework1; import java.io.IOException; impor ...
- boost asio异步读写网络聊天程序client 实例具体解释
boost官方文档中聊天程序实例解说 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...
- java网络编程(三):一个类似QQ的聊天程序
客户端: package QQ; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import ...
随机推荐
- git 常用命令总结。
引用:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137396284551 ...
- FullScreenFragment Code
package com.dexode.fragment; import android.annotation.TargetApi; import android.app.Activity; impor ...
- shopnc 商家中心添加打印商品二维码功能
需求中提到需要增加每一件商品可以打印,用于线下体验店实体商品的二维码标签,客人可以根据手机扫二维码功能进行购买 任务描述: 1.如附件实现”批量打印标签“和单个商品”打印“标签功能. 2.标签有两种” ...
- MySQL计数器表的设计
如果应用在表中保存计数器,则在更新计数器时可能碰到并发问题.计数器表在web应用中非常常见.可以用这个表缓存一个用户的朋友书.文件下载次数等.创建一张独立的表存储计数器是一种非常好的做法,这样可以使计 ...
- how to create virtual network in OS X 10.9
ifconfig lo0 alias 172.16.123.1 will add an alias IP 172.16.123.1 to the loopback adapter sudo ifcon ...
- MySQL高效获取记录总数
通常mysql获取查询记录总数我们使用如下语句: SELECT COUNT(*) FROM users WHERE k='avs'; 或:SELECT id FROM goods WHERE k=' ...
- UVA 1599 Ideal Path (HDU 3760)
两次bfs: 第一次bfs逆向搜索,得到每个点到终点的最短距离,找出最短路:第二次bfs根据最短距离可以选择满足条件的最短路. 注意!碰到这种很大数据量的题目一定要记得用scanf,printf 输入 ...
- session_cache_limiter 及 session 常见问题
我点击后退按钮,为什么之前填写的东西不见 这是因为你使用了session. 解决办法: PHP代码:-------------------------------------------------- ...
- Chapter 1. Hello, Perl/Tk
Chapter 1. Hello, Perl/Tk 内容: Perl/Tk Concepts Some Perl/Tk History Getting Started with Perl/Tk Hel ...
- yum cannot retrieve metalink for repository
Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again