2023年6月22日发(作者:)
计算机网络课程设计报告
题目:网络聊天程序的实现
姓名:刘书禄
学号:
班级:计算机三班
指导老师:文宏
测试时间:2010.9.9
测试地点:信息楼六楼
湖南科技大学计算机科学与工程学院
2010年9月 一、课程设计题目
网络聊天程序的设计与实现
二、课程设计目的
1、加深对计算机网络通信系统工作原理的理解
通过编写计算机程序实现、模拟网络的某些功能,使自己理解并掌握计算机网络基本工作原理及过程。
2、提高网络编程和应用的能力
提高实际编程能力和灵活运用所学知识解决问题的能力。培养调查研究、查阅技术文献、资料、手册及编写技术文档的能力,理论运用于实践的能力。
三、课程设计要求
1、仔细分析每一个实验的具体内容、步骤和要求,按设计要求完成任务。
2、程序设计需要完成的程序流程图、说明文档和源程序清单。
3、提交课程设报告(包含课程设计名称、课程设计题目、课程设计内容、课程设计步骤、调试过程、课程设计结果以及结果分析、心得体会)、程序源文件、可执行文件。
四、程序原理
在计算机通信系统中,有两种通信方式:面向连接的TCP和面向报文的UDP。
TCP:传输控制协议。TCP提供可靠交付的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复、并且按序到达。所以服务器和客户端的通讯使用TCP来完成。确保服务器作为“中转站”能够得到、存储、转发正确的客户信息。
UDP:用户数据报协议。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。因为客户端之间的通讯(聊天)对数据正确性的要求不是太高,偶尔出错也不会有太大的影响。
本课程设计采用TCP与UDP两种方式来实现网络聊天程序。
五、课程设计步骤
1、 TCP网络聊天程序
TCP传输控制提供可靠的,有保证的通信质量,是面向连接的通信。因此,在通信之前,通信双方就得采用建立连接。TCP通信采取C/S(客户机/服务器)模式。需要分别编写客户端程序和服务器端程序。
1) 服务器端程序编写步骤:
a) 加载套接字库,创建套接字(WSAStartup()/socket());
b) 绑定套接字到一个IP地址和一个端口上(bind());
c) 将套接字设置为监听模式等待连接请求(listen());
d) 请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
e) 用返回的套接字和客户端进行通信(send()/recv()); f) 返回,等待另一连接请求;
g) 关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
2) 客户端程序编写步骤:
a) 加载套接字库,创建套接字(WSAStartup()/socket());
b) 向服务器发出连接请求(connect());
c) 和服务器端进行通信(send()/recv());
d) 关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
2、 UDP网络聊天程序
与TCP不同,UDP在通信时并不要双方建立连接,它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的ICQ和OICQ就是使用的UDP协议。因此,本设计同样采用UDP连接方式。
程序编写步骤:
a) 加载套接字库,创建套接字(WSAStartup()/socket());
b) 绑定套接字到一个IP地址和一个端口上(bind());
c) 发送和接收数据(sendto()/recvfrom());
d) 关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
六、程序流程图
TCP UDP
七、程序源代码
TCP服务器
TCPServerDlg.h:
class CMySimpleQQ_ServerDlg : public
CDialog
{
// Construction
public:
// Dialog Data
lg)
overrides
//{{AFX_VIRTUAL(CMySimpleQQ_Ser// ClassWizard generated virtual function
enum { IDD =
CButton
CEdit
CEdit
CString
m_buttsend;
m_edit2;
m_edit1;
m_strEdit1;
g)
lParam);
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID,
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT
IDD_MYSIMPLEQQ_SERVER_DIALOG };
//{{AFX_DATA(CMySimpleQQ_ServerDCMySimpleQQ_ServerDlg(CWnd*
// standard constructor pParent = NULL);
verDlg)
protected:
virtual void
// DoDataExchange(CDataExchange* pDX);
DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
//}}AFX_VIRTUAL
// Generated message map functions
//{{AFX_MSG(CMySimpleQQ_ServerDlLPARAM lParam);
//}}AFX_DATA
OnUpdateData(WPARAM wParam, LPARAM afx_msg void OnSend();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
//服务器套接字和IP地址
SOCKET sockServer;
:
#include "stdafx.h"
#include "MySimpleQQ_Server.h"
#include "MySimpleQQ_ServerDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function
overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void
DoDataExchange(CDataExchange* pDX); //
DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
sockaddr_in addrServer;
//客服端套接字和IP地址
SOCKET sockClient;
sockaddr_in addrClient;
int addrClientLen;
};
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() :
CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void
CAboutDlg::DoDataExchange(CDataExchange*
pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg,
CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMySimpleQQ_ServerDlg dialog
CMySimpleQQ_ServerDlg::CMySimpleQQ_ServerDlg(CWnd* pParent /*=NULL*/)
:
CDialog(CMySimpleQQ_ServerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMySimpleQQ_ServerDlg)
m_strEdit1 = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a
subsequent DestroyIcon in Win32
m_hIcon =
AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void
CMySimpleQQ_ServerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMySimpleQQ_ServerDlg)
DDX_Control(pDX, IDC_SEND,
m_buttsend);
DDX_Control(pDX, IDC_EDIT2,
m_edit2);
DDX_Control(pDX, IDC_EDIT1,
m_edit1);
DDX_Text(pDX, IDC_EDIT1,
m_strEdit1);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMySimpleQQ_ServerDlg, CDialog)
//{{AFX_MSG_MAP(CMySimpleQQ_ServerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_UPDATEDATA,
OnUpdateData)
ON_BN_CLICKED(IDC_SEND,
OnSend)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMySimpleQQ_ServerDlg message handlers
UINT thread(LPVOID p)
{
//临时变量
int s=1;
CString temp;
char buffer[100]="";
CMySimpleQQ_ServerDlg
*dlg=(CMySimpleQQ_ServerDlg*)AfxGetApp()->GetMainWnd();
//接收客户端连接
dlg->sockClient=accept(dlg->sockServer,(sockaddr*)&dlg->addrClient,&dlg->addrClientLen);
//接收客服端数据
if(dlg->sockClient==INVALID_SOCKET)
dlg->m_strEdit1 +="客服端接收失败!rn";
else
{
// AfxBeginThread(&thread,0);
dlg->m_Window(true);//发送按钮有效
//提示连接成功
("【系统提示】:%s连接成功!rn",inet_ntoa(dlg->_addr));
dlg->m_strEdit1 +=temp;
dlg->PostMessage(WM_UPDATEDATA,0,0);
dlg->SetForegroundWindow();
//接收客户端消息
while(s!=SOCKET_ERROR)
{
s=recv(dlg->sockClient,buffer,100,0);
dlg->SetForegroundWindow();
if(s!=SOCKET_ERROR)
{
("%s:rnt",inet_ntoa(dlg->_addr));
dlg->m_strEdit1 +=
temp;
dlg->m_strEdit1 =
dlg->m_strEdit1 + buffer + "rn";
dlg->PostMessage(WM_UPDATEDATA,0,0);
}
}
//如果发生错误,发送中断消息给客户端
send(dlg->sockClient,"【系统提示】:连接已中断!",100,0);
dlg->m_strEdit1 += "【系统提示】:连接已中断!rn";
dlg->PostMessage(WM_UPDATEDATA,0,0);
//如果客户端连接中断,关闭套接字
dlg->m_Window(false);
closesocket(dlg->sockClient);
}
AfxEndThread(0);
return 0;
}
BOOL
CMySimpleQQ_ServerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "" menu item to system
menu.
// IDM_ABOUTBOX must be in the
system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0)
== IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu =
GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
ring(IDS_ABOUTBOX);
if (!y())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,
IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The
framework does this automatically
// when the application's main window is
not a dialog
SetIcon(m_hIcon, TRUE); //
Set big icon
SetIcon(m_hIcon, FALSE); // Set
small icon
// TODO: Add extra initialization here
m_Window(false);
WSADATA wsaData;
if(WSAStartup(0x101,&wsaData)!=0)
m_strEdit1 ="【系统提示】:初始化失败!rn";
_addr.s_addr=htonl(INADDR_ANY);
_family=AF_INET;
_port=2204;
sockServer=socket(AF_INET,SOCK_STREAM,0);
if(sockServer==INVALID_SOCKET)
m_strEdit1 +="【系统提示】:套接字创建失败!rn";
else
{
if(bind(sockServer,(sockaddr*)&addrServer,sizeof(addrServer))!=0)
m_strEdit1 +="【系统提示】:套接字绑定失败!rn";
else
{
m_strEdit1 +="【系统提示】:服务器创建成功!rn【系统提示】:等待连接 ... ...rn";
listen(sockServer,5); AfxBeginThread(&thread,0);
}
}
addrClientLen=sizeof(addrClient);
UpdateData(false);
return TRUE; // return TRUE unless
you set the focus to a control
}
void
CMySimpleQQ_ServerDlg::OnSysCommand(UINT
nID, LPARAM lParam)
{
if ((nID & 0xFFF0) ==
IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
l();
}
else
{
CDialog::OnSysCommand(nID,
lParam);
}
}
void CMySimpleQQ_ServerDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context
for painting
SendMessage(WM_ICONERASEBKGND,
(WPARAM) eHdc(), 0);
// Center icon in client rectangle
int cxIcon =
GetSystemMetrics(SM_CXICON);
int cyIcon =
GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (() - cxIcon + 1) /
2;
int y = (() - cyIcon + 1) /
2;
// Draw the icon
on(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to
display while the user drags
// the minimized window.
HCURSOR
CMySimpleQQ_ServerDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
LRESULT
CMySimpleQQ_ServerDlg::OnUpdateData(WPARAM wParam, LPARAM lParam)
{
UpdateData(false);
return 0;
}
void CMySimpleQQ_ServerDlg::OnSend()
{
// TODO: Add your control notification
handler code here
char buffer[100]="";
CString temp;
m_dowText(buffer,100);
send(sockClient,buffer,100,0);
("%s:rnt",inet_ntoa(_addr));
m_strEdit1 = m_strEdit1 + temp + buffer + "rn";
m_dowText("");
TCPClient..h:
class CMySimpleQQ_ClientDlg : public
CDialog
{
// Construction
public:
CMySimpleQQ_ClientDlg(CWnd*
pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CMySimpleQQ_ClientDlg)
enum { IDD =
IDD_MYSIMPLEQQ_CLIENT_DIALOG };
CButton m_buttDisconnect;
CButton m_buttConnect;
CButton m_buttSend;
CIPAddressCtrl m_ipaddress;
CEdit m_edit2;
CString m_strEdit1;
//}}AFX_DATA
// ClassWizard generated virtual function
overrides
//{{AFX_VIRTUAL(CMySimpleQQ_ClientDlg)
protected:
virtual void
UDP.h:
#ifndef _UDP_H_
#define _UDP_H_
#include
#include
#include
#include
#pragma comment(lib,"WS2_32")
class UDP
UpdateData(false);
}
DoDataExchange(CDataExchange* pDX); //
DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CMySimpleQQ_ClientDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID,
LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButtonConnect();
afx_msg LRESULT OnUpdateData();
afx_msg void OnButtonSend();
afx_msg void OnButtonDisconnect();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
SOCKET sockClient;
sockaddr_in addrClient;
int addrLen;
};
{
private:
static void *ListenThread(void *data);
SOCKET ListenSocket;
sockaddr_in srv;
sockaddr_in client;
public:
UDP();
~UDP();
bool SendMsg(char *Msg, int len, char *host, short port);
bool Listen(int PortNum);
};
UDP::UDP()
{
ListenSocket=INVALID_SOCKET;
WORD version=MAKEWORD(2,2);
WSADATA wsaData;
if(WSAStartup(version,&wsaData))
{
printf("Socket服务启动失败!");
fflush(0);
}
}
UDP::~UDP()
{
if(ListenSocket!=INVALID_SOCKET)
closesocket(ListenSocket);
WSACleanup();
}
bool UDP::Listen(int PortNum)
{
ListenSocket=socket(PF_INET,SOCK_DGRAM,0);
if(ListenSocket==INVALID_SOCKET)
{
printf("Socket创建失败!");
fflush(0);
return false;
}
_family=PF_INET;
_addr.s_addr=htonl(INADDR_ANY);
_port=htons(PortNum);
if(bind(ListenSocket,(struct
sockaddr*)&srv,sizeof(srv))!=0)
{
printf("Socket绑定失败!");
fflush(0);
closesocket(ListenSocket);
return false;
}
int ThreadID;
DWORD thread;
ThreadID=(int)CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(UDP::ListenThread),(void *)this,0,&thread);
ThreadID=ThreadID?0:1;
if(ThreadID)
{
printf("线程创建失败!");
return false;
}
else
return true;
}
void *UDP::ListenThread(void *data)
{
char buf[4096];
UDP *udp=(UDP *)data;
int len=sizeof(udp->client);
while(1)
{
int
result=recvfrom(udp->ListenSocket,buf,sizeof(buf)-1,0,(sockaddr *)&udp->client,(int *)&len);
if(result>0)
{
buf[result]=0;
printf("<<%s(%i):t",inet_ntoa(udp->_addr),ntohs(udp->_port));
printf("%sn",buf);
fflush(0);
}
}
}
bool UDP::SendMsg(char *Msg,int len, char
*host,short port)
{
signed int sent; hostent *hostdata;
if(atoi(host))
{
u_long ip=inet_addr(host);
hostdata=gethostbyaddr((char
*)&ip,sizeof(ip),PF_INET);
}
else
{
hostdata=gethostbyname(host);
}
if(!hostdata)
{
printf("获得计算机名错误!n");
fflush(0);
return false;
}
sockaddr_in dest;
:
#include "UDP.h"
int main(int argc,char *argv[])
{
char buffer[4096];
short listeningport;
short destport;
char *desthost;
printf("初始化中。。。n");
listeningport=200;
destport=100;
desthost="127.0.0.1";
UDP udp;
if(!(listeningport))
{
八、附录(软件截图)
_family=PF_INET;
_addr=*(in_addr
*)(hostdata->h_addr_list[0]);
_port=htons(port);
printf(">>%s(%i):n",inet_ntoa(_addr),ntohs(_port));
sent=sendto(ListenSocket,Msg,len,0,(sockaddr *)&dest,sizeof(sockaddr_in));
if(sent!=len)
{
printf("发送错误!");
fflush(0);
return false;
}
return false;
}
#endif
printf("端口%s绑定失败!n",listeningport);
return 0;
}
printf("聊天程序建立成功!
while(fgets(buffer,sizeof(buffer),stdin))
{
g(buffer,strlen(buffer),desthost,destport);
}
return 0;
} 设定
服务器
客户机
发布者:admin,转转请注明出处:http://www.yc00.com/web/1687428961a9353.html
评论列表(0条)