chat.h
typedef struct ONLINE//在線用戶
{
int fd;
char name[32];
}Online;
typedef struct msg//訊息
{
int md;//屬性(群聊:1 ,私聊:2 ,獲取在線客戶資訊:3
char txt[BUFSIZ];//內容
char from_name[32];
char to_name[32];
}MSG;
server.c
#include"chat.h"
#define MAXCONNECTION 20//最大連接佇列20
Online online[MAXCONNECTION];
void login(int fd);
void broadcast(int fd,MSG *msg);
void private(int fd,MSG *msg);
void show_online(int fd,MSG *msg);
void user_server(int client_sockfd, MSG *msg);
int main(int argc, char *argv[]){
int server_sockfd;
int client_sockfd;
int len;//資料資訊長度
char buffer[BUFSIZ];
char buf[BUFSIZ];
struct sockaddr_in server_addr;//服務器網路地址結構體
struct sockaddr_in client_addr;
int sin_size=sizeof(struct sockaddr_in);
for(int i=0;i<MAXCONNECTION;i++){
bzero(&online[i],sizeof(online[i]));
online[i].fd=-1;
}
int i=0;
int size;
memset(&server_addr,0,sizeof(server_addr)); //資料初始化--清零
void fork_comm(int client_sockfd);
void private_comm(char *name1,char *name2);
/*初始化server_addr*/
server_addr.sin_family=AF_INET;//設定為IP通信
server_addr.sin_port=htons(8000);//服務器埠號
server_addr.sin_addr.s_addr=INADDR_ANY;//服務器IP地址
/*創建服務器套接字,IPv4協議,TCP協議,*/
if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0){
perror("socket error");
return 1;
}
/*將套接字系結到服務器的網路地址上*/
if(bind(server_sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))<0){
perror("bind error");
return 1;
}
/*監聽連接請求,監聽佇列最多為20個*/
if(listen(server_sockfd,MAXCONNECTION)<0){
perror("bind error");
return 1;
}
/*回圈等待客戶端連接請求到達*/
while(1){
printf("等待客戶端連接....\n");
client_sockfd=accept(server_sockfd,(struct sockaddr*)&client_addr,&sin_size);
if(client_sockfd<0){
perror("accept error");
return 1;
}
printf("\n%s:%d is connected to server.\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
pid_t pid;
/*創建子行程處理客戶端*/
pid=fork();
if(pid==0){
login(client_sockfd);
MSG msg;
while(1){
if((recv(client_sockfd,&msg,sizeof(msg),0)<0)){
perror("recv");
}
user_server(client_sockfd,&msg);
}
}
}
/*關閉套接字*/
close(server_sockfd);
close(client_sockfd);
return 0;
}
/* 客戶端處理函式 */
void user_server(int client_sockfd, MSG *msg){
switch (msg->md)
{
case 1:
broadcast(client_sockfd,msg);
break;
case 2:
private(client_sockfd,msg);
break;
case 3:
show_online(client_sockfd,msg);
break;
default:
break;
}
}
void login(int fd){
char buf[BUFSIZ];
if((recv(fd,buf,sizeof(buf),0))<0){
perror("recv");
}
printf("%s進入了聊天室.\n",buf);
//將新加入的用戶加到在線用戶串列里
for(int i=0;i<MAXCONNECTION;i++){
if(online[i].fd==-1){
online[i].fd=fd;
strcpy(online[i].name,buf);
break;
}
}
}
void broadcast(int fd,MSG *msg){
printf("%s 正在群發訊息:%s\n",msg->from_name,msg->txt);
for(int i=0;i<MAXCONNECTION;i++){
if(online[i].fd!=-1){
if((send(online[i].fd,&msg,sizeof(msg),0))<0){
perror("send");
}
}
}
}
void private(int fd,MSG *msg){
printf("%s 正在私發訊息給 %s:%s\n",msg->from_name,msg->to_name,msg->txt);
for(int i=0;i<MAXCONNECTION;i++){
if((online[i].fd==-1)||(strncmp(online[i].name,msg->to_name,strlen(msg->to_name))!=0)){
continue;
}
if((send(online[i].fd,&msg,sizeof(msg),0))<0){
perror("send");
}
break;
}
}
void show_online(int fd,MSG *msg){
printf("%s 查看當前在線人員\n",msg->from_name);
int len;
char buf[1024] = {0};
for(int i=0; i<MAXCONNECTION; i++){
if(online[i].fd != -1)
{
strcat(buf,online[i].name);
len=strlen(buf);
buf[len]=' ';
}
}
strcpy(msg->txt,buf);
if((send(fd,&msg,sizeof(msg),0))<0){
perror("send");
}
printf("查看成功\n");
}
client.c
#include"chat.h"
int l;
char name[32];
void all(int fd);
void private(int fd);
void menu();
void use_menu(int client_sockfd);
void recv_msg(int client_sockfd);
void login(int fd);
void chat_all(int fd);
void chat_one(int fd);
void online_list(int fd);
int main(int argc, char *argv[]){
int client_sockfd;
int len;
struct sockaddr_in remote_addr;//服務器端網路地址結構體
char buf[BUFSIZ];//資料傳送的緩沖區
char buffer[BUFSIZ];
char recv_buf[BUFSIZ];
memset(&remote_addr,0,sizeof(remote_addr));//資料初始化--清零
remote_addr.sin_family=AF_INET; //設定為IP通信
remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服務器IP地址 //本地機
remote_addr.sin_port=htons(8000); //服務器埠號
/*創建客戶端套接字--IPv4協議,TCP協議*/
if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0){
perror("socket error");
return 1;
}
/*將套接字系結到服務器的網路地址上*/
if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0){
perror("connect error");
return 1;
}
printf("Connected to server!\n");
login(client_sockfd);
use_menu(client_sockfd);
close(client_sockfd);
return 0;
}
void menu(){
printf("*****\t歡迎使用本聊天室 *****\n");
printf("**\t 1.群聊\n");
printf("**\t 2.私聊\n");
printf("**\t 3.查看當前在線人數\n");
printf("**\t 0.退出\n");
}
void login(int fd){
printf("請輸入您的昵稱:\n");
scanf("%s",name);
if((send(fd,name,strlen(name),0))<0){//將昵稱發送給server
perror("send");
}
}
void chat_all(int fd){
MSG msg;
msg.md = 1;//群聊屬性
strcpy(msg.from_name,name);
printf("請輸入你要發送的資訊:\n");
scanf("%s",msg.txt);
if((send(fd,&msg,sizeof(msg),0))<0){
perror("send");
}
printf("發送成功!\n");
}
void chat_one(int fd){
MSG msg;
msg.md=2;//私聊屬性
printf("請輸入你要發送資訊的物件:\n");
scanf("%s",msg.to_name);
strcpy(msg.from_name,name);
printf("請輸入你要發送的資訊:\n");
scanf("%s",msg.txt);
if((send(fd,&msg,sizeof(msg),0))<0){
perror("send");
}
printf("發送成功!\n");
}
void online_list(int fd){
MSG msg;
msg.md=3;//獲取在線用戶資訊屬性
strcpy(msg.from_name,name);
if((send(fd,&msg,sizeof(msg),0))<0){
perror("send");
}
}
void use_menu(int client_sockfd){
pid_t pid;
pid=fork();
if(pid==0){//創建子行程接受訊息
recv_msg(client_sockfd);
}
else if(pid>0){
int ch;
menu();
while(1){
printf("請輸入您要做的操作\n");
scanf("%d",&ch);
while(getchar() != '\n');
switch (ch){
case 1://發送群聊訊息
chat_all(client_sockfd);
break;
case 2://發送私聊訊息
chat_one(client_sockfd);
break;
case 3://獲取在線客戶串列
online_list(client_sockfd);
break;
default:
break;
}
}
}
}
void recv_msg(int client_sockfd){
MSG msg;
while(1){
//判斷接收到的訊息型別
bzero(&msg,sizeof(msg));
if((recv(client_sockfd,&msg,sizeof(msg),0)<0)){
perror("recv");
}
switch (msg.md)
{
case 1://群聊訊息
printf("群聊訊息:%s:%s\n",msg.from_name,msg.txt);
break;
case 2:
printf("私聊訊息:%s:%s\n",msg.from_name,msg.txt);
break;
case 3://在線客戶串列訊息
printf("當前在線用戶:\n");
online_list(client_sockfd);
break;
default:
break;
}
}
}


uj5u.com熱心網友回復:
有沒有大佬教教孩子啊

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/284821.html
標籤:C++ 語言
