跪求一局域网聊天程序或思路

scwinter 2008-11-05 01:01:23
创建一个局域网上的分布式聊天程序,通过该程序,用户可以和网内运行同一程序的所有用户实时聊天。

在任一时候,当用户启动该程序的时候,他可以自动搜索网上在线的用户,加入当前的公共聊天空间,获取当时完整的谈话纪录。如果没有找到任何其他用户,该用户进入等待,等其他程序加入。

聊天空间和相关历史纪录由所有程序共同维护,没有特定的服务器程序来统一协调。任何时候只要还有一个用户在线,就可以保存当前聊天完整的历史纪录。如果所有程序都退出,当前历史纪录自动丢失。

程序同时支持实时传送文件的功能。在用户聊天时候,可以随时向所有在线用户发送文件,文件传输时候必须保证通话继续流畅。

任何用户都可以随时加入和退出,用户的加入和退出必须及时在所有用户的程序上反映出来。


实现要求

程序由C++实现,网络通信通过Socket实现,界面可以和例子里面的不一样
实现上面详细介绍里面的功能,至少必须同时支持4个用户
网络通信必须流畅,反馈信息必须及时
...全文
221 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
西园软件 2008-11-10
  • 打赏
  • 举报
回复
我的资源
西园软件 2008-11-10
  • 打赏
  • 举报
回复
我上传到我的资料里,你直接去下吧!!
西园软件 2008-11-10
  • 打赏
  • 举报
回复
这程序我以前写过,有三种模式,这个是比较实用的面向连接的异步模式,
不允许发过长的贴子,这里只发个服务器端的代码.
看不懂的话,加个好友,我把文章和调试通过的源代码送给你.


服务器端和客户端程序分别为:
Chat_RoomS.h

#define SER_MESSAGE WM_USER+100
#define MaxNumber 5

int WSA_return;
WSADATA WSAData;

SOCKET server_hSocket;
SOCKET Listen_hSocket;

struct sockaddr_in server_addr;
struct sockaddr_in Listen_addr;
int Listen_addrlen=sizeof(Listen_addr);
int fromlen=sizeof(server_addr);

BOOL server_bErr;
UINT server_uPort;
char ShowText[1024];
char InputText[256];
char Receive_Text[256];

SOCKET nSocket[MaxNumber];
char *ClientIP[MaxNumber];
int i;

char ComeMsg[30]=" 走进聊天室\r\n";
char LeaveMsg[30]=" 离开聊天室\r\n";
char LeaveMsg1[30]=" 异常离开\r\n";

BOOL APIENTRY Hostname_ipDlgPro(HWND hDlg,UINT message,
WPARAM wParam,LPARAM lParam);

Chat_RoomS.c

#include<winsock.h>
#include"resource.h"
#include"Chat_RoomS.h"

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
DialogBox(hInstance,(LPCTSTR)"DIALOG1",NULL,(DLGPROC)Hostname_ipDlgPro);

return(TRUE);
}


BOOL APIENTRY Hostname_ipDlgPro(HWND hDlg,UINT message,
WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
WSA_return=WSAStartup(0x0002,&WSAData);
if(WSA_return!=0)
{
MessageBox(NULL,"初始化失败!","警告!",MB_OK);
WSACleanup();
}
return TRUE;

case SER_MESSAGE:
switch(lParam)
{
case FD_ACCEPT:
Listen_hSocket=accept(server_hSocket,(LPSOCKADDR)&Listen_addr,&Listen_addrlen);

for(i=0;i<MaxNumber;i++)
{
if(nSocket[i]==0)
{
nSocket[i]=Listen_hSocket;
if(WSAAsyncSelect(nSocket[i],hDlg,SER_MESSAGE,
FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE)>0)
MessageBox(NULL,"异步模式创建失败!","警告!",MB_OK);
ClientIP[i]=inet_ntoa(Listen_addr.sin_addr);
break;
}
}
if(i<MaxNumber)
{
strcat(ShowText,ClientIP[i]);
strcat(ShowText,ComeMsg);
SetDlgItemText(hDlg,IDC_SHOWTEXT,ShowText);
for(i=0;i<MaxNumber;i++)
if(nSocket[i]!=0)
{
send(nSocket[i],ClientIP[i],strlen(ClientIP[i]),0);
send(nSocket[i],ComeMsg,strlen(ComeMsg),0);
}
}
return TRUE;

case FD_READ:
for(i=0;i<MaxNumber;i++)
if(nSocket[i]==wParam)
{
recv(nSocket[i],Receive_Text,256,0);
strcat(ShowText,ClientIP[i]);
strcat(ShowText,":\r\n ");
strcat(ShowText,Receive_Text);
SetDlgItemText(hDlg,IDC_SHOWTEXT,ShowText);
for(i=0;i<MaxNumber;i++)
if(nSocket[i]!=0)
{
send(nSocket[i],ClientIP[i],strlen(ClientIP[i]),0);
send(nSocket[i],":\r\n ",strlen(":\r\n "),0);
send(nSocket[i],Receive_Text,strlen(Receive_Text),0);
}
}

return TRUE;
case FD_WRITE:
return TRUE;
case FD_CLOSE:
for(i=0;i<MaxNumber;i++)
if(nSocket[i]==wParam)
{
strcat(ShowText,ClientIP[i]);
strcat(ShowText,LeaveMsg);
SetDlgItemText(hDlg,IDC_SHOWTEXT,ShowText);
closesocket(nSocket[i]);
nSocket[i]=0;
for(i=0;i<MaxNumber;i++)
if(nSocket[i]!=0)
{
send(nSocket[i],ClientIP[i],strlen(ClientIP[i]),0);
send(nSocket[i],LeaveMsg,strlen(LeaveMsg),0);
}
}
return TRUE;

default:
for(i=0;i<MaxNumber;i++)
if(nSocket[i]==wParam)
{
strcat(ShowText,ClientIP[i]);
strcat(ShowText,LeaveMsg1);
SetDlgItemText(hDlg,IDC_SHOWTEXT,ShowText);
closesocket(nSocket[i]);
nSocket[i]=0;
for(i=0;i<MaxNumber;i++)
if(nSocket[i]!=0)
{
send(nSocket[i],ClientIP[i],strlen(ClientIP[i]),0);
send(nSocket[i],LeaveMsg1,strlen(LeaveMsg1),0);
}
}
return TRUE;
}
return FALSE;

case WM_COMMAND:

switch(LOWORD(wParam))
{
case IDC_SETSERVER:
if(server_hSocket!=0)
{
closesocket(server_hSocket);
server_hSocket=0;
}
if(server_hSocket==0)
{
if((server_hSocket=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)
{
MessageBox(NULL,"建立套接字失败!","警告!",MB_OK);
break;
}
if(WSAAsyncSelect(server_hSocket,hDlg,SER_MESSAGE,
FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE)>0)
{
MessageBox(NULL,"异步模式创建失败!","警告!",MB_OK);
break;
}
}
server_addr.sin_family=AF_INET;
server_addr.sin_addr.S_un.S_addr=INADDR_ANY;
server_uPort=GetDlgItemInt(hDlg,IDC_PORTUINT,&server_bErr,TRUE);
server_addr.sin_port=htons((u_short)server_uPort);

if(bind(server_hSocket,(LPSOCKADDR)&server_addr,sizeof(server_addr))==SOCKET_ERROR)
{
MessageBox(NULL,"绑定端口失败!","警告",MB_OK);
break;
}
if(listen(server_hSocket,5)==SOCKET_ERROR)
{
MessageBox(NULL,"侦听失败!","警告!",MB_OK);
break;
}
strcpy(ShowText,"服务器建立成功!\r\n");
SetDlgItemText(hDlg,IDC_SHOWTEXT,ShowText);
return TRUE;

case IDC_SHOWTEXT:
if(HIWORD(wParam)==EN_CHANGE)
if(strlen(ShowText)>1024-256)
strcpy(ShowText,"");
case IDC_INPUTTEXT:
if(HIWORD(wParam)==EN_CHANGE)
{
GetDlgItemText(hDlg,IDC_INPUTTEXT,InputText,256);
if(InputText[strlen(InputText)-1]=='\n')
{
strcat(ShowText,"管理员:\r\n ");
strcat(ShowText,InputText);
SetDlgItemText(hDlg,IDC_SHOWTEXT,ShowText);
for(i=0;i<MaxNumber;i++)
if(nSocket[i]!=0)
{
send(nSocket[i],"管理员:\r\n ",strlen("管理员:\r\n "),0);
send(nSocket[i],InputText,strlen(InputText),0);
}
strcpy(InputText,"");
SetDlgItemText(hDlg,IDC_INPUTTEXT,InputText);
}
}
return TRUE;

case IDCANCEL:
WSAAsyncSelect(server_hSocket,hDlg,0,0);
closesocket(server_hSocket);
WSACleanup();
EndDialog(hDlg,TRUE);
return TRUE;

}
}
return FALSE;
}


icosagon 2008-11-07
  • 打赏
  • 举报
回复
去看电驴的源码吧
wjdlt_1997 2008-11-07
  • 打赏
  • 举报
回复
说到底楼主是想要源码……
cyj626 2008-11-07
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 scwinter 的回复:]
谢谢 就是这样 有哪位高人可以给个源码么?
[/Quote]
不懂,不会
scwinter 2008-11-07
  • 打赏
  • 举报
回复
谢谢 就是这样 有哪位高人可以给个源码么?
nickywang2004 2008-11-06
  • 打赏
  • 举报
回复
我记得UDP可以广播
如果是这样的话
你可以开机的时候可以广播自己登录信息
如果有同样开了此软件的机器返回一个消息,告诉你他的存在,同时两边在在线名单里面添加对方IP
然后以后就可以用这个IP来聊天了
我觉得局域网做的话还不至于用到P2P的算法
scwinter 2008-11-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 Wolf0403 的回复:]
lz 要求的是 P2P 类型的东西。。
[/Quote]
嗯 就是 是 p2p的
Wolf0403 2008-11-05
  • 打赏
  • 举报
回复
lz 要求的是 P2P 类型的东西。。
jia_xiaoxin 2008-11-05
  • 打赏
  • 举报
回复
楼主用过飞鸽传书么?
下载过开源的IPMessage么?
我觉的IPMessage的功能就是你所需要的。
我曾经用IPMessage改过一个聊天程序。
太乙 2008-11-05
  • 打赏
  • 举报
回复
呵呵,没细看lz的需求,不对的地方,见谅!
太乙 2008-11-05
  • 打赏
  • 举报
回复
用服务器管理线程池,
客户端的连接请求送到服务器,由服务器分配,然后客户端自己socket连接!
内容概要:本文系统介绍了基于核主成分分析(KPCA)的故障检测方法,重点实现了T²和Q统计指数的可视化,并提供了完整的Matlab代码实现与仿真分析流程。该方法通过核函数映射将原始非线性过程数据转换至高维特征空间,进行主成分提取与降维处理,进而构建T²和Q两种统计量用于监控系统运行状态,有效识别工业过程中的早期故障与异常行为。文中详细阐述了KPCA的数学原理、故障检测机制、控制限计算方法,并结合实际案例展示其在复杂非线性系统中的应用效果与优越性,具有较强的工程实用性。; 适合人群:具备一定信号处理、机器学习理论基础及Matlab编程能力的研究生、科研人员和工程技术人员,特别适用于从事工业过程监控、故障诊断、智能制造等相关领域的研究人员。; 使用场景及目标:①应用于化工、电力、制造等行业中关键设备的在线故障监测与早期预警;②作为学术研究中非线性降维与异常检测算法的对比基准;③帮助开发者掌握KPCA模型构建、参数调优及T²-Q统计图可视化等核心技术环节。; 阅读建议:建议读者结合所提供的Matlab代码进行动手实践,深入理解KPCA算法的核心步骤,重点关注核函数选择、主成分数确定及统计量阈值设定等关键参数的影响,以提升故障检测的灵敏度与准确性。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧