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 ...
随机推荐
- 学php之翻译wordpress(1)
单看文件结构,wordpress分了3个文件夹 wp-admin,wp-content,wp-includes 和零散的一堆php,暂时不清楚各自的分工 入口文件是index.php <?php ...
- [转]IP地址-子网掩码-默认网关
IP地址:是给每个连接在Internet上的主机分配的一个32bit地址.地址有两部分组成,一部分为网络地址,另一部分为主机地址.IP地址分为A.B.C.D.E 5类.常用的是B和C两类.网络地址的位 ...
- Python 装饰器学习以及实际使用场景实践
前言 前几天在看Flask框架,对于非常神奇的@语法,不是非常的理解,回来补装饰器的功课.阅读很多的关于装饰器的文章,自己整理一下,适合自己的思路的方法和例子,与大家分享. app = Flask(_ ...
- 连接Xively云
1.注册Xively开发账号 在https://xively.com注册一个开发账户,收到激活邮件后激活,注意,如果登陆后无法进入develop页面,请退出重新登陆. 2.添加设备 3.获取FeedI ...
- python 数据类型之数float
1.float 对象有一个重要的方法is_intger.如果这个float对应在转化为int时不会有精度的丢失就返回True,不然就返回False #!/usr/bin/python #!coding ...
- nginx的请求接收流程(二)
在ngx_http_process_request_line函数中,解析完请求行之后,如果请求行的uri里面包含了域名部分,则将其保持在请求结构的headers_in成员的server字段,heade ...
- Nginx 配置指令的执行顺序(十)
运行在 post-rewrite 阶段之后的是所谓的 preaccess 阶段.该阶段在 access 阶段之前执行,故名preaccess. 标准模块 ngx_limit_req 和 ngx_lim ...
- Nginx 变量漫谈(三)
也有一些内建变量是支持改写的,其中一个例子是 $args. 这个变量在读取时返回当前请求的 URL 参数串(即请求 URL 中问号后面的部分,如果有的话 ),而在赋值时可以直接修改参数串.我们来看一个 ...
- 检测android的版本的办法
http://www.cnblogs.com/wzh206/archive/2010/05/02/1726076.html 如何判断Android系统的版本 随着Android版本的增多,在不同的版本 ...
- HP-UX磁带备份错误收集
磁带备份命令: make_tape_recovery -Av 默认备份至/dev/rmt/0mn. 如果有多个磁带机,那么需要使用下面命令 make_tape_recovery -Av -a /de ...