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

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

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

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

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

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


实现要求

程序由C++实现,网络通信通过Socket实现,界面可以和例子里面的不一样
实现上面详细介绍里面的功能,至少必须同时支持4个用户
网络通信必须流畅,反馈信息必须及时
...全文
223 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连接!
内容概要:本文围绕“新能源发电接入弱电网的宽频带振荡机理及抑制方法”开展深入研究,依托Matlab/Simulink平台完整复现了相关博士论文的核心内容。研究聚焦于新能源并网系统在弱电网条件下引发的宽频带振荡问题,通过构建光伏并网逆变器、虚拟同步发电机(VSG)等关键设备的精确动态模型,采用阻抗建模、序阻抗分析、扫频法和小信号稳定性分析等先进理论工具,系统揭示了锁相环、电流控制环与电网阻抗之间复杂的动态交互机制及其诱发不稳定振荡的内在机理。在此基础上,提出了包括自适应控制、虚拟阻抗、增益调度等多种针对性的抑制策略,并通过详尽的仿真验证了其有效性。该资源不仅提供了核心研究成果的复现代码与模型,还整合了大量电力系统稳定性、微电网优化、智能算法应用等领域的配套案例,构成一套体系完整、理论与实践紧密结合的高水平科研参考资料。; 适合人群:具备电力系统分析、新能源并网技术、自动控制理论等专业知识背景,熟练掌握Matlab/Simulink仿真工具的研究生、高校科研人员及电力电子与电力系统领域的工程技术人员。; 使用场景及目标:① 深入探究新能源并网系统在弱电网环境下面临的稳定性挑战与宽频带振荡的产生根源;② 系统学习并掌握阻抗建模、扫频分析等现代电力电子系统稳定性评估的关键技术与方法论;③ 实践复现高水平学术论文(特别是博士论文)中的复杂模型与核心结论,为自身的课题研究、论文撰写与项目攻关提供坚实的理论依据和技术验证;④ 借助丰富的配套案例资源,进行新算法开发、模型优化与综合技术方案的设计与测试。; 阅读建议:建议读者结合文中提供的网盘链接,下载完整的Matlab代码与Simulink仿真模型进行动手实践。在学习过程中,应着重关注核心模型的搭建逻辑、参数设计依据以及不同控制策略的实现细节,通过主动修改系统参数、切换控制方案等方式进行对比仿真分析,从而深刻理解理论分析、数学模型与实际仿真结果之间的内在联系,充分发挥该资源在科研学习与技术创新中的最大价值。

65,211

社区成员

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

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