当前位置:编程学习 > C#/ASP.NET >>

vs2008sp1 mfc socket服务器程序


// csocketDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "csocket.h"
#include "csocketDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CcsocketDlg 对话框




CcsocketDlg::CcsocketDlg(CWnd* pParent /*=NULL*/)
: CDialog(CcsocketDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CcsocketDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_list);
DDX_Control(pDX, IDC_EDIT1, m_edit);
DDX_Control(pDX, IDC_SEND, m_send);
}

BEGIN_MESSAGE_MAP(CcsocketDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_SEND, &CcsocketDlg::OnBnClickedSend)
END_MESSAGE_MAP()


// CcsocketDlg 消息处理程序

BOOL CcsocketDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码
count = 0;  //显示行记数
//初始化50个socket实例
for(int i=0;i<50;i++)
{
msgsock[i] = NULL;
}
//设置显示框控件
m_list.InsertString(0,_T("消息"));
m_list.SetColumnWidth(435);
m_edit.SetLimitText(99);

//初始化socket的临时变量
int errorcode = 0,iRet = -1;
CString dispbuff;

//取得主机名和IP地址
GetLocalHostName(m_sHostName);
GetIPAddress(m_sHostName,m_sIPAddress);

//设定地址
serv_addr.sin_addr.s_addr = inet_addr((LPSTR)(LPCTSTR)m_sIPAddress);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = 5000;  //直接填写端口号更好
addlen = sizeof(serv_addr);
m_send.EnableWindow(FALSE);
//创建socket
sock = socket(AF_INET,SOCK_STREAM,0);
if (sock == SOCKET_ERROR)
{
errorcode = WSAGetLastError();
dispbuff.Format(_T("初始化 --> 服务器socket创建失败,错误号=%d!"),errorcode);
m_edit.SetWindowText(_T("服务器socket创建失败!"));
m_list.InsertString(count++,dispbuff);
}
else
{
m_edit.SetWindowText(_T("服务器socket创建成功!"));
m_list.InsertString(count++,_T("初始化 --> 服务器socket创建成功!"));
}
//绑定地址
iRet = bind(sock,(sockaddr*)&serv_addr,addlen);
if (iRet == SOCKET_ERROR)
{
errorcode = WSAGetLastError();
dispbuff.Format(_T("初始化 --> 服务器地址bind绑定错误,错误号=%d!"),errorcode);
m_edit.SetWindowText(_T("服务器地址bind绑定错误!"));
m_list.InsertString(count++,dispbuff);
}
else
{
m_edit.SetWindowText(_T("服务器地址bing绑定成功!"));
m_list.InsertString(count++,_T("服务器地址bind绑定成功!"));
}
iRet = listen(sock,5);
if(iRet == SOCKET_ERROR)
{
errorcode = WSAGetLastError();
dispbuff.Format(_T("初始化 --> 服务器listen监听设置失败,错误号=%d!"),errorcode);
}
else
{
m_edit.SetWindowText(_T("服务器listen监听设置成功!"));
m_list.InsertString(count++,_T("初始化 --> 服务器listen监听设置成功!"));

//开始使用线程不停地接收新的连接请求并进行数据I/O
//m_edit.SetWindowText(_T(""));
AfxBeginThread(&thread,0);
}

return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CcsocketDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CcsocketDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}

int CcsocketDlg::getcount()
{
for(int i=0;i<50;i++)
{
if(msgsock[i] == NULL)
{
return i;
}
}
return -1;
}

void CcsocketDlg::sendtoall(SOCKET s,CString str)
{
CString sendbuff,dispbuff;
//显示
dispbuff = _T("Server端 --> For其他的Client连接send:") + str;
m_list.InsertString(count++,dispbuff);
//m_list.Sroll(size);

//循环发送数据
sendbuff = _T("IP=") + m_sIPAddress+_T("send to connect:")+str;
for(int i=0;i<50;i++)
{
if((msgsock[i] != NULL)&&(msgsock[i] != s))
{
send(msgsock[i],(LPSTR)(LPCTSTR)sendbuff,100,0);               //发送数据
}
}
}

int CcsocketDlg::GetLocalHostName(CString& sHostName)
{
CString szHostName;
int nRetCode;
nRetCode = gethostname((LPSTR)(LPCTSTR)szHostName,sizeof(szHostName));
if(nRetCode != 0)
{
szHostName = _T("Not available");  //出现错误
return WSAGetLastError();
}
sHostName = szHostName;
return 0;
}

int CcsocketDlg::GetIPAddress(const CString& sHostName,CString& sIPAddress)
{
struct hostent FAR *lpHostEnt = gethostbyname((LPSTR)(LPCTSTR)sHostName);
if(lpHostEnt = NULL)
{
sIPAddress = _T("");  //出现错误
return WSAGetLastError();
}

LPSTR lpAddr1 = lpHostEnt->h_addr_list[0];  错误在这
if(lpAddr1)
{
struct in_addr inAddr;
memmove(&inAddr,lpAddr1,4);
sIPAddress = inet_ntoa(inAddr);
if(sIPAddress.IsEmpty())
sIPAddress = _T("Not avaliable");
}
return 0;
}

void CcsocketDlg::OnBnClickedSend()
{
// TODO: 在此添加控件通知处理程序代码
CString buff,sendbuff,dispbuff;
CSize size;
size.cx = 0;
size.cy = 30;
m_edit.GetWindowText((LPTSTR)(LPCTSTR)buff,99);
m_edit.SetWindowText(_T(""));
dispbuff = _T("Server端 --> 向Client发送:") + buff;
m_list.InsertString(count++,dispbuff);
m_list.ScrollWindow(size.cx,size.cy);

//循环向客户发信息
sendbuff = _T("IP=")+m_sIPAddress+_T("send :") + buff;
for(int i=0;i<50;i++)
if(msgsock[i] != NULL)
send(msgsock[i],(LPSTR)(LPCTSTR)sendbuff,100,0);
}

CcsocketDlg::~CcsocketDlg()
{
for (int i=0;i<50;i++)
{
if (msgsock[i] != NULL)
{
send(msgsock[i],"Server端结束:Server Disconnect!",100,0);
}
}
}

UINT thread(LPVOID p)
{
int ithd;
CString buff,tellbuff;
CSize size;
size.cx = 0;
size.cy = 30;
int s=1,msgcount,loop=1,flag=0;
int errorcode=0,iRet=-1;
CcsocketDlg *dlg = (CcsocketDlg*)AfxGetApp()->GetMainWnd();

tellbuff.Format(_T("工作区 --> 启动第%d次线程:准备设置accept接受等待!"),ithd);
dlg->m_list.InsertString(dlg->count++,tellbuff);

//处理线程的启动计数
ithd++;
if(ithd > 1000)
{
ithd = 0;
}

//获得客户端目前已有的全部连接的数目的下一个还没有用的msgsock实例
msgcount = dlg->getcount();
if(msgcount = -1) loop = 0;
if(loop)
{
s = 1;  //接受数据的字节数目,用于标志是否成功接收数据
//显示提示
tellbuff.Format(_T("初始化 --> 第%d个socket的accept开始设置!"),msgcount);
dlg->msgsock[msgcount] = accept(dlg->sock,(sockaddr*)&(dlg->serv_addr),&(dlg->addlen));
if (dlg->msgsock[msgcount] == INVALID_SOCKET)
{
errorcode = WSAGetLastError();
tellbuff.Format(_T("初始化 --> 第%d个socket的accept接受设置失败,错误号=%d!"),msgcount,errorcode);
dlg->m_edit.SetWindowText(_T("初始化 --> 服务器accept的接受设置失败"));
dlg->m_list.InsertString(dlg->count++,tellbuff);
}
else
{
tellbuff.Format(_T("初始化 --> 第%d个socket的accept接受设置成功!"),msgcount);
dlg->m_edit.SetWindowText(_T("初始化 --> 服务器accept的接受设置成功!"));
dlg->m_list.InsertString(dlg->count++,tellbuff);

//启动线程循环接受数据
AfxBeginThread(&thread,0);  //thread改为p
dlg->SetForegroundWindow();

//显示提示
tellbuff.Format(_T("初始化 --> 第%d个socket的连接成功!"),msgcount);
dlg->m_list.InsertString(dlg->count++,_T("连接成功"));
CString stls;
stls.Format(_T("%s"),inet_ntoa(dlg->serv_addr.sin_addr));
dlg->m_list.InsertString(dlg->count++,stls);
dlg->m_list.ScrollWindow(size.cx,size.cy);
dlg->m_edit.SetWindowText(_T(""));
dlg->m_send.EnableWindow(TRUE);
while (s != SOCKET_ERROR)
{
//循环接受数据
s = recv(dlg->msgsock[msgcount],(LPSTR)(LPCTSTR)buff,100,0);
dlg->SetForegroundWindow();
if (s != SOCKET_ERROR)
{
//显示
tellbuff.Format(_T("Server端 --> 接受当前Client的数据:<%s>"),buff);
dlg->m_list.InsertString(dlg->count++,tellbuff);
dlg->m_list.ScrollWindow(size.cx,size.cy);
dlg->sendtoall(dlg->msgsock[msgcount],buff);
}
}
//发送失败信息
send(dlg->msgsock[msgcount],"连接失败:Disconnected!",100,0);
dlg->m_list.InsertString(dlg->count++,_T("连接失败:Disconneed!"));
dlg->m_list.ScrollWindow(size.cx,size.cy);
dlg->msgsock[msgcount] = NULL;
for (int i=0;i<50;i++)
{
if(dlg->msgsock[i]!=NULL) flag=1;
}
if(flag !=1)dlg->m_send.EnableWindow(FALSE);
closesocket(dlg->msgsock[msgcount]);
}
}
//终止线程
AfxEndThread(0);
return 0;
}


错误提示:csocket.exe 中的 0x001038c3 处未处理的异常: 0xC0000005: 读取位置 0x0000000c 时发生访问冲突
我查了一下说是使用了未定义的内存,真找不出来
大家帮帮忙了,非常感谢!! --------------------编程问答--------------------
int CcsocketDlg::GetIPAddress(const CString& sHostName,CString& sIPAddress)
{
struct hostent FAR *lpHostEnt = gethostbyname((LPSTR)(LPCTSTR)sHostName);
if(lpHostEnt = NULL)
{
sIPAddress = _T("");  //出现错误
return WSAGetLastError();
}
//错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这
//错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这
LPSTR lpAddr1 = lpHostEnt->h_addr_list[0];//错误在这错误在这错误在这错误在
//错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这
//错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这错误在这
if(lpAddr1)
{
struct in_addr inAddr;
memmove(&inAddr,lpAddr1,4);
sIPAddress = inet_ntoa(inAddr);
if(sIPAddress.IsEmpty())
sIPAddress = _T("Not avaliable");
}
return 0;
}

标注不是很明显,颜色没有显示不知道为啥。。。再补充一下 --------------------编程问答--------------------
补充:.NET技术 ,  VC.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,