/*****makefile******/
gcc -o server server.c
gcc -Wall -o login login.c `pkg-config --cflags --libs gtk+2.0` -lcrypt -lpthread
/*客户端*/
/* connectUDP.h - connectUDP */
#include "connectsock.h"
/*------------------------------------------------------------------------
* connectUDP - connect to a specified UDP service on a specified host
*------------------------------------------------------------------------
*/
int
connectUDP(const char *host, const char *service )
/*
* Arguments:
*
*
*/
- name of host to which connection is desired
host
service - service associated with the desired port
{
}
return connectsock(host, service, "udp");
/* connectsock.h - connectsock */
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
/* INADDR_NONE */
/*------------------------------------------------------------------------
* connectsock - allocate & connect a socket using TCP or UDP
*------------------------------------------------------------------------
*/
int
connectsock(const char *host, const char *service, const char *transport )
/*
* Arguments:
*
*
*
*/
host
service
transport - name of transport protocol to use ("tcp" or "udp")
- name of host to which connection is desired
- service associated with the desired port
{
struct hostent *phe;
struct servent *pse;
/* pointer to host information entry
*/
/* pointer to service information entry */
struct protoent *ppe;
struct sockaddr_in sin; /* an Internet endpoint address
int s, type;
/* socket descriptor and socket type
/* pointer to protocol information entry*/
*/
*/
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
/* Map service name to port number */
if ( pse = getservbyname(service,transport) )
sin.sin_port = pse->s_port;
else if ((sin.sin_port=htons((unsigned short)atoi(service))) == 0)
{
printf("can't get \"%s\" service entry\n", service);
return 0;
}
/* Map host name to IP address, allowing for dotted decimal */
if ( phe = gethostbyname(host) )
memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )
{
printf("can't get \"%s\" host entry\n", host);
return 0;
}
/* Map transport protocol name to protocol number */
if ( (ppe = getprotobyname(transport)) == 0)
{
printf("can't get \"%s\" protocol entry\n", transport);
return 0;
}
/* Use protocol to choose a socket type */
if (strcmp(transport, "udp") == 0)
type = SOCK_DGRAM;
else
type = SOCK_STREAM;
/* Allocate a socket */
s = socket(PF_INET, type, ppe->p_proto);
if (s < 0)
{
printf("can't create socket: \n");
return 0;
}
/* Connect the socket */
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
printf("can't connect to %s.%s: \n", host, service);
return 0;
}
return s;
}
/*********login.c***********/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "connectUDP.h"
#define MSGSIZE 255
#define MAXFRIENDS 20
typedef struct _message
{
char guestname[10];//用户名
char passwd[10];//用户密码
int
flags; //1:注册信息 2:登录验证信息 3:退出信息 4:qun chat
//5:对服务器来说转发信息 ,对用户来说是好友发来聊天信息 7:修改密码
//6:对客户端来说,它是服务器发来的用户表更新的信息
char peername[10];//发送到用户的用户名
char meg[MSGSIZE+1];//发送的消息
}message;//定义一个信息类型。
int number;//记录下次更新前好友数。
int sss;
int msgno;
message newmessage[10];
int nn[10];
typedef struct _users//记录用户
{
GtkWidget *uname;//用户名
GtkWidget *pwd;//用户密码
}USERS;
char uname[10];//保存登陆用户名
char passwd[10];//保存登陆用户密码
int sock;//用来通信的套接字。
typedef struct _rusers//记录注册用户时信息
{
GtkWidget *uname;//用户名
GtkWidget *pwd;//用户密码
GtkWidget *okpwd;//确认密码
}RUSERS;
typedef struct _friend//记录注册用户时信息
{
char uname[10];//用户名
guint status;//在线状态.0 不在线。1 在线
}FRIEND;
typedef struct _friends//记录注册用户时信息
{
guint number;//好友个数。
FRIEND friend[MAXFRIENDS];//好友表。
}FRIENDS;
FRIENDS friends;//好友表。
GtkList *List;//好友列表控件。
int loginstatus;//标识登陆 是否成功的。
int exit_QQ;//记录方程是否退出的。退出置 0,启动置 1;
struct _thread_
{
GtkWidget *dialog;//聊天 DIALOG。
guint status;//是否已开了聊天窗口,是则 1,不是则 0;
GtkWidget *output;//发送消息编辑框
GtkWidget *input;//消息显示列表控件。
message smsg;//聊天窗口对应发送信息变量。
}chat_thread[MAXFRIENDS];//好友聊天窗口信息。
struct _thread_ q_chat;
GtkWidget *main_dialog;//主界面窗口
GtkWidget *dstry;//保存要销毁 dialog
GtkWidget *dstry1;//保存要销毁 dialog
GtkWidget *dstry2;//保存要销毁 dialog
gint quit(GtkWidget *widget,GdkEvent *event,gpointer data)
{
gtk_main_quit();
return FALSE;
}
void DialogOKClicked( GtkButton * button, gpointer data)
{
gtk_widget_destroy(GTK_WIDGET(data));
}
GtkWidget *AddWidget( GtkWidget *widget,GtkWidget *packingbox)
{
gtk_box_pack_start(GTK_BOX(packingbox),widget,FALSE,TRUE,10);
return widget;
}
void MessageBox(gchar *gtxt1, gchar *gtxt2)//一对话框的形式的提示信息
{
GtkWidget *dialogwindow;
GtkWidget *dialogwidget;
dialogwindow=gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dialogwindow),"提示信息");
gtk_container_set_border_width(GTK_CONTAINER(dialogwindow),15);
gtk_window_set_position(GTK_WINDOW(dialogwindow),GTK_WIN_POS_CENTER);
dialogwidget=AddWidget(gtk_label_new(gtxt1),GTK_DIALOG(dialogwindow)->vbox);
dialogwidget=AddWidget(gtk_label_new(gtxt2),GTK_DIALOG(dialogwindow)->vbox);
dialogwidget
=
AddWidget(gtk_button_new_with_label("
确
定
"),GTK_DIALOG(dialogwindow)->action_area);
gtk_signal_connect(GTK_OBJECT(dialogwidget),"clicked",GTK_SIGNAL_FUNC(Dialog
OKClicked),dialogwindow);
gtk_signal_connect(GTK_OBJECT(dialogwidget),"destroy",GTK_SIGNAL_FUNC(quit),
NULL);
dialogwidget
=
AddWidget(gtk_button_new_with_label("
取
消
"),GTK_DIALOG(dialogwindow)->action_area);
gtk_signal_connect(GTK_OBJECT(dialogwidget),"clicked",GTK_SIGNAL_FUNC(Dialog
OKClicked),dialogwindow);
gtk_window_set_modal(GTK_WINDOW(dialogwindow),TRUE);
gtk_widget_show_all(dialogwindow);
gtk_main();
}
gint loginf(GtkWidget *login,USERS *user)
{
loginstatus=0;
if(strcmp(gtk_entry_get_text(GTK_ENTRY(((USERS *)user)->uname)),"") == 0 ||
strcmp(gtk_entry_get_text(GTK_ENTRY(((USERS *)user)->pwd)),"") == 0 )
{
MessageBox("用户名和密码不能为空","请重新登录!");
return -1;
}
strcpy(uname,gtk_entry_get_text(GTK_ENTRY(((USERS *)user)->uname)));
strcpy(passwd,gtk_entry_get_text(GTK_ENTRY(((USERS *)user)->pwd)));
///
message msg;
int len;
len=sizeof(message);
memset(&msg,0,len);
strcpy(msg.guestname,uname);
strcpy(msg.passwd,passwd);
msg.flags=2;
write(sock,(char *)&msg,len);
////
while(1)
{
if(loginstatus!=0)
break;
}
if(loginstatus==1)
{
gtk_widget_destroy(GTK_WIDGET(dstry));
g_print("进入聊天平台\n");
void maindialog();
maindialog();
}
return 0;
}
void registff(GtkWidget *regist,RUSERS *user)
{
if(strcmp(gtk_entry_get_text(GTK_ENTRY(((RUSERS *)user)->uname)),"") == 0 ||
strcmp(gtk_entry_get_text(GTK_ENTRY(((RUSERS *)user)->pwd)),"") == 0 ||
strcmp(gtk_entry_get_text(GTK_ENTRY(((RUSERS *)user)->okpwd)),"") == 0)
{
MessageBox("用户名和密码及确认密码不能为空","请确认输入!");
return;
}
if(strcmp(gtk_entry_get_text(GTK_ENTRY(((RUSERS
*)user)->pwd)),gtk_entry_get_text(GTK_ENTRY(((RUSERS *)user)->okpwd)) ) != 0)
{
MessageBox("密码与确认密码不一致","请确认输入!");
return;
}
////
message msg;
int len;
len=sizeof(message);
memset(&msg,0,len);
strcpy(msg.guestname,gtk_entry_get_text(GTK_ENTRY(((RUSERS
*)user)->uname)));
strcpy(msg.passwd,gtk_entry_get_text(GTK_ENTRY(((RUSERS *)user)->pwd)));
msg.flags=1;
write(sock,(char *)&msg,len);
///
gtk_widget_destroy(GTK_WIDGET(dstry1));
}
void registing()
{
GtkWidget *wnd;
GtkWidget *table;
GtkWidget *entry;
RUSERS user;
GtkWidget *regist;
wnd=gtk_dialog_new();
dstry1=wnd;
gtk_window_set_title((GtkWindow *)wnd,"注册窗口");
gtk_window_set_default_size(GTK_WINDOW(wnd),200,180);
gtk_container_set_border_width(GTK_CONTAINER(wnd),15);
gtk_window_set_position(GTK_WINDOW(wnd),GTK_WIN_POS_CENTER);
table=gtk_table_new(4,2,TRUE);
gtk_container_add(GTK_BOX(GTK_DIALOG(wnd)->action_area),table);
entry = gtk_label_new("用户名:");
gtk_table_attach(GTK_TABLE(table),entry,0,1,0,1,GTK_FILL,GTK_FILL,0,0);
entry = gtk_label_new("输入密码:");
gtk_table_attach(GTK_TABLE(table),entry,0,1,1,2,GTK_FILL,GTK_FILL,0,0);
entry = gtk_label_new("再次输入密码:");
gtk_table_attach(GTK_TABLE(table),entry,0,1,2,3,GTK_FILL,GTK_FILL,0,0);
user.uname=gtk_entry_new_with_max_length(10);
gtk_table_attach(GTK_TABLE(table),user.uname,1,2,0,1,GTK_FILL,GTK_FILL,0,0);
user.pwd=gtk_entry_new_with_max_length(10);
gtk_entry_set_visibility(GTK_ENTRY(user.pwd),FALSE);