linux聊天室程序如何实现

64次阅读
没有评论

共计 16720 个字符,预计需要花费 42 分钟才能阅读完成。

这篇文章主要介绍“linux 聊天室程序如何实现”的相关知识,丸趣 TV 小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“linux 聊天室程序如何实现”文章能帮助大家解决问题。

代码:

#ifndef _i_h
 
#define _i_h
 
#include  math.h 
#include  stdio.h 
#include  sys/socket.h 
#include  arpa/inet.h 
#include  netinet/in.h 
#include  unistd.h 
#include  sys/types.h 
#include  sys/stat.h 
#include  fcntl.h 
#include  stdlib.h 
#include  errno.h 
#include  string.h 
#include  inttypes.h 
#include  time.h 
#include  sys/ioctl.h  
#include  net/if.h 
#include  signal.h 
#include  ncurses.h 
#include  math.h 
 
#define sevr_ip  127.0.0.1 
#define sevr_port 8081
#define cntnt_len 150
#define msg_len sizeof(struct msg)
#define addr_len sizeof(struct sockaddr)
#define usr_len sizeof(struct user)
#define prt_len 8
#define hstr_len sizeof(struct chat_history)
 
/* declare global variables */
int mainfd;/* used as chat histroy file handle*/
int sockfd;/* used as socket local handle */
int count;
struct sockaddr_in server;
 
/* msg is used for communicating message */
struct msg
 int flag; /* flag meaning:1,ordinary; 2,log msg; 3,reg msg, other,file*/
 int id_from;
 int id_to;
 char content[cntnt_len];
 char append[10]; 
 
/* user is used information list */
struct user
 int id;
 char name[10];
 char password[10];
 char *p_chatlog;
 struct sockaddr user_addr; 
/* chat_history used for reading chat history */
struct chat_history
 char content[cntnt_len];
 char time[25];
 int to;
 int from;
 int count;
 
/* i_functions below is funtions needed by both client and sever */
extern int i_saveto_chat(struct msg *pmsg);
 
int i_clean_stdin ()
 while (\n  == getchar())
 {
 continue;
 }
 
 return(0);
 
int i_print(char *pmsg, int size)
 int i = 1;
 
 for (i; i = size; i++)
 { if (*pmsg !=  \n)
 { printf( %c , *pmsg);
 pmsg ++;
 }
 else
 { return(0);
 }
 }
 
 return(0);
int i_input(char *p_input)
 char c =  \0 
 int i; 
 
 for (i = 0; i   cntnt_len; i++)
 { p_input[i] = getchar();
 if (p_input[i] == \n )
 { return(0); 
 } 
 }
 
 printf( you have input long enough!\n 
 return(0);
int i_socket(int domain, int type, int protocol)
 int fd; 
 
 if ((fd = socket(domain, type, protocol)) == -1)
 {
 perror( creat socket error: 
 exit(1);
 }
 
 return(fd); 
 
int i_bind(int fd, const struct sockaddr *addr, int namelen)
 if (-1 == bind(fd, addr, namelen))
 {
 perror( i_bind error: 
 exit(1);
 }
 
 return (0);
 
int i_recvfrom(int fd, void *buf, size_t len, int flags, 
 struct sockaddr *addr, int *size)
{ 
 if (-1 == recvfrom(fd, buf, len, flags, addr, size))
 {
 perror( i_recvfrom error: 
 exit(1); 
 }
 
 return(0);
 
int i_sendto(int fd, void *buf, size_t len, int flags,
 struct sockaddr *addr, int size)
 if (-1 == sendto(fd, buf, len, flags, addr, size))
 {
 perror( i_sendto error 
 exit(1); 
 }
 
 return (0);
 
int i_open(const char *pathname, int flags)
 int fd;
 if ((fd = open(pathname, flags)) == -1)
 {
 perror( open_failed 
 exit(1);
 }
 
 return (fd);
int i_read(int fd, void *msg, int len)
 if(-1 == read(fd, msg, len))
 {
 perror( i_read error 
 exit(1);
 }
 return(0);
int i_write(int fd, void *msg, int len)
 if (-1 == write(fd, msg, len))
 {
 perror( i_write error 
 exit(0);
 }
 return(0);
 
/* init a socket,file and server addr */
int i_init()
 mainfd = i_open(./chat_log , o_rdwr|o_creat);
 sockfd = i_socket(af_inet, sock_dgram, 0);
 
 /* initialize server address */
 bzero(server, sizeof(server));
 server.sin_family = af_inet;
 inet_pton(af_inet,  127.0.0.1 ,  server.sin_addr);
 server.sin_port = htons(sevr_port);
 
 perror( init 
 
 return (0);
 
char *i_get_time()
 time_t time_now;
 time(time_now);
 
 return(ctime( time_now));
int i_lseek(int fd, off_t size, int position)
 if (-1 == lseek(fd, size, position))
 {
 perror( seek error 
 exit(1);
 }
 return(0);
int i_saveto_chat(struct msg *pmsg)
{ 
 struct chat_history hstr;
 
 
 bzero(hstr, hstr_len);
 count = count + 1;
 hstr.count =count;
 hstr.from = pmsg- id_from;
 hstr.to = pmsg- id_to;
 strncpy(hstr.content, pmsg- content, cntnt_len);
 strncpy(hstr.time, i_get_time(), 25);
 
 i_lseek(mainfd, 0, seek_end);
 
 i_write(mainfd,  hstr, hstr_len);
 
 return(0);
 
int i_print_history(int len, int i)
 struct chat_history chat_reader;
 int j;
 int position;
 
 bzero(chat_reader, hstr_len);
 if (i != 0)
 {
 position = len*i*hstr_len;
 i_lseek(mainfd, position, seek_end);
 }
 else
 {
 position = len*i*hstr_len;
 
 i_lseek(mainfd, hstr_len, seek_set);
 }
 
 for (j = 1; j  = len; j++)
 {
 
 i_read(mainfd,  chat_reader, hstr_len);
 printf( \n#item%d:id%dto id%d \n , j,
 chat_reader.from, chat_reader.to);
 i_print(chat_reader.content, cntnt_len);
 printf(\n time:%s\n , chat_reader.time);
 }
 
 return(0);
 
#endif

代码二:

#include  i.h 
 
int user_list_fd;
 
/* start:initialization */
int init()
 i_init();
 
 user_list_fd = i_open(./user_list , o_rdwr|o_creat);
 
 struct user usr;
 /* init the user list file s fist user to 0*/
 memset((struct user*) usr,  \0 , sizeof(struct user));
 i_lseek(user_list_fd, 0, seek_set);
 i_write(user_list_fd, (char*) usr, usr_len);
 
 /* bind the struct sockaddr_in server to the sockfd */
 i_bind(sockfd, (struct sockaddr*) server, addr_len); 
 
 struct chat_history apple; 
 
 bzero(apple, hstr_len);
 i_lseek(mainfd, 0, seek_set);
 i_write(mainfd,  apple, hstr_len);
 i_lseek(mainfd, -hstr_len, seek_end);
 i_read(mainfd,  apple, hstr_len);
 count = apple.count;
 
 return(0);
/* end:initialization */
 
/* start:message control */
int send_msg(struct msg *msg_recv, struct sockaddr *addr)
 int i;
 struct user usr;
 
 /* a common message come */
 printf( a ordinar message come !\n 
 
 i = msg_recv- id_to;
 i_lseek(user_list_fd, i*usr_len, seek_set);
 i_read(user_list_fd,  usr, usr_len);
 strncpy(msg_recv- append, usr.name, 10);
 
 i_sendto(sockfd, msg_recv, msg_len, 0,
  (usr.user_addr), addr_len);
 
 printf(id%d send a message to id%d sucess!\n , msg_recv- id_from, msg_recv- id_to);
 
 return(0);
int check_login(struct msg *msg_recv, struct sockaddr *addr)
 int i = msg_recv- id_from;;
 struct user usr;
 
 /* a login requet */
 printf( a login request come!\n 
 
 /* get the id s information */
 i_lseek(user_list_fd, i*usr_len, seek_set);
 i_read(user_list_fd,  usr, usr_len);
 
 int n;
 n = strcmp(usr.password, msg_recv- content);
 /*  如果验证成功,则发送成功信息  */
 if (n == 0)
 {
 /* save user new address */
 i_lseek(user_list_fd, -usr_len, seek_cur);
 usr.user_addr = *addr;
 i_write(user_list_fd,  usr, usr_len);
 /* tell user pass */
 i_sendto(sockfd, (struct msg*)msg_recv, sizeof(struct msg), 0,
  (usr.user_addr), addr_len);
 
 }
 else
 {
 /*  出错的话的 respond */
 if (0 != n)
 { printf( id %d login error.\n , i);
 bzero(msg_recv- content, cntnt_len); 
 msg_recv- flag = -1;
 i_sendto(sockfd, (struct msg*)msg_recv, sizeof(struct msg), 0,
  (usr.user_addr), addr_len);
 
 }
 return(1);
 }
 printf(id %d login sucess!\n , i); 
 
 return(0);
int reg_user(struct msg *msg_recv, struct sockaddr *addr)
 struct user usr;
 
 printf( a regit requet come:\n 
 
 /* find the last user and hava the please to add a new user */
 int n;
 i_lseek(user_list_fd, -usr_len, seek_end);
 i_read(user_list_fd,  usr, usr_len);
 /*  把新用户的信息赋值到 usr 然后填入到 user list file 中  */
 const char *name;
 const char *password;
 
 name =  (msg_recv- content[0]);
 password =  (msg_recv- content[10]);
 strcpy((usr.name), name);
 strcpy(usr.password, password);
 memcpy((usr.user_addr),addr, addr_len);
 
 usr.id = (usr.id + 1);
 i_lseek(user_list_fd, 0, seek_end);
 i_write(user_list_fd,  usr, usr_len);
 
 msg_recv- id_from = usr.id;
 /* regist to the user list then tell the user reg success */
 i_sendto(sockfd, (struct msg*)msg_recv, sizeof(struct msg), 0,
 addr, addr_len); 
 
 printf(id %d regist sucess!\n , usr.id);
 
 return(0);
 
int msg_cntl()
 struct msg msg_recv;
 struct sockaddr addr_recv;
 
 printf( begin listen input...\n 
 int size = addr_len;
 
 for (;;)
 { bzero( msg_recv, msg_len);
 i_recvfrom(sockfd,  msg_recv, sizeof(struct msg), 0,
  addr_recv,  size);
 printf( message received...\n 
 
 i_saveto_chat(msg_recv);
 
 switch (msg_recv.flag)
 {
 case 1 :
 send_msg(msg_recv,(struct sockaddr*) addr_recv);/* send ordinary chat */
 break;
 case 2 :
 check_login(msg_recv, (struct sockaddr*) addr_recv);
 break; 
 case 3 :
 reg_user(msg_recv, (struct sockaddr*) addr_recv);
 break;
 default :
 break;
 }
 }
 return(0);
/* end:message control*/
/* start:exit_sys()*/
int exit_sys()
 close(sockfd);
 close(mainfd);
 close(user_list_fd);
 printf( exit system 
 kill(0, sigabrt);
 
 exit(0);
/* end:exit_sys()*/
 
/* start:chat_history*/
int get_page_size()
 struct chat_history page_size_reader;
 
 i_lseek(mainfd, -hstr_len, seek_end);
 i_read(mainfd,  page_size_reader, hstr_len);
 
 return(page_size_reader.count);
 
int read_chat_history()
 printf( ****char*history*** 
 printf((n-nextpage; p-prepage; q-quit)\n 
 
 int page_num;/* */
 int remains;
 int berry = get_page_size();
 
 
 page_num = berry / 8;
 remains = berry % 8;
 
 if (remains != 0)
 page_num ++;
 else
 page_num = page_num;
 
 printf( there are %d page total %d items , 
 page_num, berry);
 
 int i = -1;
 
 while (1)
 { 
 char flag; 
 
 if ((berry + i*8)  = 0)
 { printf( (%d~%d)\n , (berry + i*8), (berry + (i+1)*8));
 
 i_print_history(prt_len, i);
 
 printf( @@@\n 
 while (\n  == (flag = getchar()))
 { }
 
 switch (flag)
 {
 case  p  :
 i--;
 break;
 case  n  :
 i++;
 break;
 case  q  :
 return(0);
 default :
 break;
 } 
 if (i  = 0)
 {
 printf( have at the end!\n 
 printf( return to menu!\n 
 } 
 }
 else
 { printf( (1~%d)\n , remains); 
 
 i_print_history(remains, 0);
 
 printf( #########over##############\n 
 
 return(0);
 } 
 }
 
 return(0);
/* end:chat_history*/
/* start:menu*/
int menu()
 sleep(1);
 
 printf( ----------help----menu---------\n 
 printf( \t r--report to user\n 
 printf( \t c--chat history\n 
 printf( \t h--help menu\n 
 printf( \t e--exit the system\n 
 printf( ----------help_menu---------\n 
 
 int command = 0;
 
 printf( input command 
 command = getchar();
 switch(command)
 {
 
 case  c :
 read_chat_history();
 break;
 case  e :
 exit_sys();
 break;
 case  r :
 //report();
 //break;
 default :
 menu();
 break;
 }
 getchar();
 
 return(0);
/* end:menu*/
int main()
 init();
 pid_t pid;
 switch (pid = fork())
 {
 case -1 :
 perror( fork error\n 
 exit(1);
 break;
 case 0 :
 msg_cntl();
 break;
 default :
 menu();
 break;
 }
 
 return(0);
}

代码三:

#include  i.h 
 
#define start_port 8089
 
struct sockaddr_in my_addr;
int my_id;
 
int my_log();/* declare funtion*/
 
/* */
int i_send_msg()
{ 
 int id;
 struct msg the_msg;
 char end =  @ 
 
 printf( input recver id: 
 scanf(%d ,  id);
 getchar();
 printf( \ninput content: 
 i_input(the_msg.content); 
 
 char flag =  y 
 
 if (1)
 {
 the_msg.flag = 1;
 the_msg.id_from = my_id;
 the_msg.id_to = id;
 
 i_sendto(sockfd,  the_msg, sizeof(struct msg), 0,
 (struct sockaddr*) server, sizeof(struct sockaddr));
 
 i_saveto_chat(the_msg); /* save to history */
 
 printf(send to id:%d success.\n , my_id);
 return(0);
 }
 else
 return(1);
 
 return(0);
 
int reply()
 return(0);
int send_file()
 return(0);
/* start:initialize */
int init()
{ 
 struct ifreq req;
 struct sockaddr_in *host;
 int port;
 
 i_init();
 /* init user addr */
 bzero(my_addr, sizeof(struct sockaddr));
 my_addr.sin_family = af_inet;
 strcpy(req.ifr_name,  lo 
 if ( ioctl(sockfd, siocgifaddr,  req)   0 ) /* get local ip address */
 {
 perror( get local ip error 
 exit(1);
 } 
 
 host = (struct sockaddr_in*) (req.ifr_addr);
 printf(ip: %s\n , inet_ntoa(host- sin_addr));
 
 memcpy(my_addr, (struct sockaddr_in*) (req.ifr_addr),
 sizeof(struct sockaddr_in));
 
 port = start_port;
 
 do
 {
 port++;
 my_addr.sin_port = htons(port);
 bind(sockfd, (struct sockaddr*) my_addr,
 sizeof(struct sockaddr)); 
 } 
 while (errno == eaddrinuse);
 
 struct chat_history apple; 
 
 memset(apple,  b , hstr_len);
 i_lseek(mainfd, 0, seek_set);
 apple.count = 0;
 i_write(mainfd,  apple, hstr_len);
 i_lseek(mainfd, -hstr_len, seek_end);
 i_read(mainfd,  apple, hstr_len);
 count = apple.count;
 
 
 printf(port:%d\n , port); 
 printf( init successful!!!\n  
 
 return(0);
 
/* end:initialize */
/* start:chat_history*/
int get_page_size()
 struct chat_history page_size_reader;
 
 i_lseek(mainfd, -hstr_len, seek_end);
 i_read(mainfd,  page_size_reader, hstr_len);
 
 return(page_size_reader.count);
 
int read_chat_history()
 printf( ****char*history*** 
 printf((n-nextpage; p-prepage; q-quit)\n 
 
 int page_num;/* */
 int remains;
 int berry = get_page_size();
 
 
 page_num = berry / 8;
 remains = berry % 8;
 
 if (remains != 0)
 page_num ++;
 else
 page_num = page_num;
 
 printf( there are %d page total %d items , 
 page_num, berry);
 
 int i = -1;
 
 while (1)
 { 
 char flag; 
 
 if ((berry + i*8)  = 0)
 { printf( (%d~%d)\n , (berry + i*8), (berry + (i+1)*8));
 
 i_print_history(prt_len, i);
 
 printf( @@@\n 
 while (\n  == (flag = getchar()))
 { }
 
 switch (flag)
 {
 case  p  :
 i--;
 break;
 case  n  :
 i++;
 break;
 case  q  :
 return(0);
 default :
 break;
 } 
 if (i  = 0)
 {
 printf( have at the end!\n 
 printf( return to menu!\n 
 } 
 }
 else
 { printf( (1~%d)\n , remains); 
 
 i_print_history(remains, 0);
 
 printf( #########over##############\n 
 
 return(0);
 } 
 }
 
 return(0);
/* end:chat_history*/
/* start:exit_sys*/
void exit_sys()
 close(sockfd);
 close(mainfd);
 kill(0, sigabrt);
 
 exit(0);
/* end:exit_sys*/
 
/* start:menu*/
int print_menu()
 printf( \n--------------help--menu----------------\n 
 printf( \t h--help munu\n 
 printf( \t s--send message\n 
 printf( \t r--reply to\n 
 printf( \t c--chat history\n 
 printf( \t f--send files\n 
 printf( \t e--exit the system\n 
 printf( ----------------help--menu----------------\n 
int get_input(char *command)
{ 
 printf( scanf( %c , command);
 
 return(1);
int menu()
 /* to avoid the output at mixed with the sub process */
 sleep(1);
 
 print_menu();
 
 char command;
 
 while (1 == get_input( command))
 { 
 switch(command)
 {
 case  h :
 print_menu();
 break; 
 case  s :
 i_send_msg();
 break;
 case  r :
 reply();
 break;
 case  f :
 send_file();
 break;
 case  c :
 read_chat_history();
 break;
 case  e :
 exit_sys();
 break;
 default :
 printf( 
 break;
 }
 }
 return(0);
/* end:menu*/
/* start:message contol :send_msg and recv_msg */
int ordnary_msg_recv(struct msg *pmsg)
 char time_info[25];
 char end_symble;
 end_symble =  
 
 /* handle the msg */
 printf(message:from %s(id%d) to u:\n , pmsg- append, pmsg- id_from);
 i_print(pmsg- content, msg_len);
 printf(\n\t%s , i_get_time());
 
 return(0);
int file_msg_recv(struct msg *pmsg)
int handle_msg(struct msg *pmsg)
{ 
 if (pmsg- flag == 1)
 { ordnary_msg_recv(pmsg);
 return(0);
 }
 else if (pmsg- flag  = 4)
 { file_msg_recv(pmsg);
 return(0);
 } 
 return(0);
int listen_msg()
 struct msg msg_recv;
 struct sockaddr addr_recv;
 int len = addr_len;
 
 printf( begin listen...\n 
 
 for ( ; ; )
 { 
 i_recvfrom(sockfd,  msg_recv, msg_len, 0, 
  addr_recv,  len);
 
 i_saveto_chat(msg_recv); /* save to history */
 
 ordnary_msg_recv(msg_recv);
 }
 
/* end:message contol*/
 
/* start:log process :login and regist */
int login()
 /* input id:*/
 printf( *****login \n 
 printf( id: 
 scanf(%d ,  my_id);
 /* input password*/
 char password[15];
 printf(\npassword(*less 15 char): 
 scanf(%s , password);
 getchar();
 
 /* send login information */
 struct msg log_msg;
 
 bzero(log_msg, msg_len);
 log_msg.flag = 2;
 log_msg.id_from = my_id;
 log_msg.id_to = 0;
 strncpy(log_msg.content, password, 15);
 
 i_saveto_chat(log_msg); /* save to history */
 
 i_sendto(sockfd, (struct msg*) log_msg, msg_len, 0, 
 (struct sockaddr*) server, sizeof(struct sockaddr));
//printf(log_msg : %d\n , log_msg.id_from);
//printf(password: %s\n , log_msg.content);
 /* after input msg ,wait for server respond*/
 struct sockaddr in_addr;
 int len = addr_len;
 i_recvfrom(sockfd, (struct msg*) log_msg, msg_len,0,
  in_addr,  len);
 if (2 == log_msg.flag)
 {
 printf( login success\n 
 return(0);
 } 
 else
 { printf( login error:%s\n , log_msg.content);
 printf( please relog..\n 
 menu();
 }
 
 return (0);
int regist()
 printf( *****regist \n 
 /* input chat name */
 char name[10];
 
 bzero(name, 10);
 printf(input your chat name(less 8 char): 
 scanf(%s , name);
 
 //name[9] =   /* add a ; symbol in the end of name */
 /* input password */
 char password[15];
 
 bzero(password, 15);
 printf(\ninput your password(less 14 char): 
 scanf(%s , password);
 
 /* send regist information*/
 struct msg reg_msg;
 
 bzero(reg_msg, msg_len);
 reg_msg.flag = 3;
 reg_msg.id_from = 0;
 reg_msg.id_to = 0;
 bzero(reg_msg.content, cntnt_len);
 strncpy(reg_msg.content, name, 10);
 strncpy((reg_msg.content[10]), password, 15);
 reg_msg.content[25] =  \n 
 
 i_saveto_chat(reg_msg); /* save to history */
 
 /* send regist informatin to server */
 i_sendto(sockfd, (struct msg*) reg_msg, sizeof(struct msg), 0, 
 (struct sockaddr*) server, addr_len);
 /* after input msg ,wait for server respond*/
 printf( wating for server reply...\n 
 
 struct sockaddr in_addr;
 struct msg msg_back;
 int len = addr_len;
 
 bzero(in_addr, addr_len);
 bzero(msg_back, msg_len);
 i_recvfrom(sockfd,(struct msg*) msg_back, msg_len,0,
  in_addr,  len);
 
 /* check whether pass */
 if (3 != msg_back.flag)
 { printf( error: %s \n , msg_back.content);
 exit(1);
 }
 else
 my_id = msg_back.id_to;
 printf( congratulate! you have regist 
  id %s(id %d) success\n , msg_back.content, msg_back.id_to);
 
 login();
 
 return(0); 
 
int my_log()
 /* choose login or regist*/
 char flag;
 printf(are you want login or regist(l/r)\n 
 scanf(%c ,  flag);
 getchar();
 switch (flag){
 case  l  :
 login();
 break;
 case  r  :
 regist();
 break;
 default :
 printf( error input\n 
 my_log();
 break;
 }
 return (0);
/* end:log */
 
int main()
 init();
 printf( \n************welcome!************\n 
 my_log();
 
 pid_t pid;
 
 switch (pid = fork())
 {
 case -1 :
 perror( fork error!\n 
 exit(1);
 break;
 case 0 :
 listen_msg();
 break;
 default :
 menu();
 break;
 }
}

关于“linux 聊天室程序如何实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注丸趣 TV 行业资讯频道,丸趣 TV 小编每天都会为大家更新不同的知识点。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-15发表,共计16720字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)