資源簡(jiǎn)介
簡(jiǎn)單功能如下
1. 服務(wù)器端接收用戶(hù)信息,處理后轉(zhuǎn)發(fā)給其他用戶(hù),如有用戶(hù)登錄或退出,服務(wù)器通知所有人;
2. 群聊:用戶(hù)發(fā)送的信息所有人都可以接收,接收的信息前面顯示發(fā)送者的昵稱(chēng)和發(fā)送時(shí)間;
3. 私聊:可以選定用戶(hù)發(fā)送信息,其他用戶(hù)看不到,該用戶(hù)也使用相同的方式回復(fù)私聊信息;
4. 保存和查看聊天記錄,僅可查看自己保存的聊天記錄,保存和讀取聊天記錄時(shí)需要使用文件鎖; 保存和查看聊天記錄,聊天記錄保存在“./msgsave_昵稱(chēng)”文件中(“昵稱(chēng)”為保存者自己的昵稱(chēng));
5. 服務(wù)器的出錯(cuò)信息打印輸出到屏幕上,同時(shí)發(fā)送給系統(tǒng)日志(/var/log/messages)。
代碼片段和文件信息
#include? //?頭文件
#include?
#include?
#include??//定義數(shù)據(jù)結(jié)構(gòu)sockaddr_in
#include??//定義socket函數(shù)以及數(shù)據(jù)結(jié)構(gòu)??Socket的英文原義是“孔”或“插座”,用于描述IP地址和端口,是一個(gè)通信鏈的句柄,可以用來(lái)實(shí)現(xiàn)不同虛擬機(jī)或不同計(jì)算機(jī)之間的通信
#include?
#include?
#include?
#include?
#include?
#include?
#include
#include?
#include??
#include?
GtkWidget?*window;???//登錄窗口
GtkWidget?*home; //主窗口
int?clientfdb_file;
struct?sockaddr_in?clientaddr;?
char?user_name[50];
char?fname[]=“/var/tmp/“;
int?sem_id;?
int?init_sem(int?sem_id?int?init_value){
union?semun{
int?val;
struct?semid_ds?*buf;
unsigned?short?*array;
};
union?semun?sem_union;
sem_union.val?=?init_value;
if(semctl(sem_id?0?SETVAL?sem_union)?==?-1){
perror(“Initialize?semaphore“);
return?-1;
}
return?0;
}
int?del_sem(int?sem_id){
union?semun{
int?val;
struct?semid_ds?*buf;
unsigned?short?*array;
};
union?semun?sem_union;
if(semctl(sem_id?1?IPC_RMID?sem_union)==-1){
perror(“Delete?semaphore“);
return?-1;
}
}
//P?操作函數(shù)
int?sem_p(int?sem_id){
struct?sembuf?sem_b;
sem_b.sem_num?=?0;
sem_b.sem_op?=?-1;
sem_b.sem_flg?=?SEM_UNDO;
if(semop(sem_id?&sem_b?1)==-1){
perror(“P?operation“);
return?-1;
}
return?0;
}
//V?操作函數(shù)
int?sem_v(int?sem_id){
struct?sembuf?sem_b;
sem_b.sem_num?=?0;
sem_b.sem_op?=?1;
sem_b.sem_flg?=?SEM_UNDO;
if(semop(sem_id?&sem_b?1)?==?-1){
perror(“V?operation“);
return?-1;
}
return?0;
}
//處理登錄
void?deal_pressed(GtkWidget?*button?gpointer?entry){
int?sendbytes;
char?*buff;
struct?hostent?*host;
char?wel[]=“Welcome“;
//host?=?gethostbyname(“127.0.0.1“);???//本地地址
host?=?gethostbyname(“127.0.0.1“);
????????buff?=?(char?*)malloc(9);
const?gchar??*text?=?gtk_entry_get_text(GTK_ENTRY(entry));
if(strlen(text)==0){
printf(“不能為空\(chéng)n“);?????????//?提示?不能為空
}
else{
if?((clientfd?=?socket(AF_INET?SOCK_STREAM?0))?==?-1)
{
perror(“fail?to?create?socket“);
exit(1);
}
bzero(&clientaddr?sizeof(clientaddr));
clientaddr.sin_family?=?AF_INET;????//創(chuàng)建套接字時(shí),用該字段指定地址家族,對(duì)于TCP/IP協(xié)議的,必須設(shè)置為AF_INET
clientaddr.sin_port?=?htons((uint16_t)atoi(“8787“));
clientaddr.sin_addr?=?*((struct?in_addr?*)host->h_addr);//host->h_addr?是一個(gè)?char*,需要的是?struct?in_addr?*。因此,我轉(zhuǎn)換host->h_addr?成?struct?in_addr?*,這是個(gè)指針,取他的內(nèi)容,即?*,然后賦給左邊?
if?(connect(clientfd?(struct?sockaddr?*)&clientaddr?sizeof(struct?sockaddr))?==?-1)
{
perror(“fail?to?connect“);
exit(1);
}
if?((sendbytes?=?send(clientfd?text?strlen(text)?0))?==?-1)
????{
perror(“fail?to?send“);
exit(1);
????}
if?(recv(clientfd?buff?7?0)?==?-1)
{
perror(“fail?to?recv“);
exit(1);
}
if(strcmp(buffwel)==0){
strcpy(user_nametext);
gtk_widget_destroy(window);
}else{
//??彈窗?提醒?提示?昵稱(chēng)重復(fù)
GtkWidget?*dialog;
dialog?=?gtk_m
評(píng)論
共有 條評(píng)論