网络编程的一些笔记
2010年08月14日
今天辛苦比照标准程序,终于把socket程序调通。
注意:用vc6.0环境,创建对话框程序,在创建的时候勾选上,csocket支持。
程序有两个,一个客户端程序,一个服务器端程序。
服务器端:
两个csocket对象,
mysocket m_recv; 用来接收和发送消息
mysocket m_server;用来监听连接和响应消息
mysocket 继承 CSocket,
重载两个消息函数:
void mysocket::OnAccept(int nErrorCode)
{
CSocket::OnAccept(nErrorCode);
((CMyseverDlg*)(AfxGetApp()->m_pMainWnd))->ShowAccept();
CSocket::OnAccept(nErrorCode);
}
void mysocket::OnReceive(int nErrorCode)
{
CSocket::OnReceive(nErrorCode);
((CMyseverDlg*)(AfxGetApp()->m_pMainWnd))->ShowMsg();
}
对话框类中:
消息启动m_server, 接收连接,并转嫁到m_recv
void CMyseverDlg::ShowAccept()
{
m_server.Accept(m_recv);//使连接转移到m_recv上
AfxMessageBox("Server端连接成功");
}
消息启动m_server,转嫁到m_recv接收消息,并且显示。
void CMyseverDlg::ShowMsg()
{
char buf[255];
m_recv.Receive(buf,255);
CString msg;
msg.Format("%s",buf);
m_conversation+="对方:"+msg+"\r\n";
UpdateData(false);
}
通过 m_recv 直接发送消息
void CMyseverDlg::Onsend()
{
UpdateData(true);
m_recv.Send(m_content, 255); //发送数据
m_conversation=m_conversation+"自己:"+m_content+"\r\n";
m_content="";
UpdateData(false);
}
客户端:
一个CSocket类对象
class mysocket : public CSocket(){。。。}
mysocket myclient;
myclient.Create(1001); //使用1001号端口
if(myclient.Connect(m_ip, 1000)) //连接目标IP m_ip,1000端口
重载一个系统消息函数,用于发现消息,并且启动对话框的显示;
void mysocket::OnReceive(int nErrorCode)
{
((CNetclientDlg*)(AfxGetApp()->m_pMainWnd))->ShowMsg();
CSocket::OnReceive(nErrorCode);
}
对话框
发送消息
void CNetclientDlg::Onsend()
{
UpdateData(TRUE); //更新数据,使m_msg得到当前框中文本
myclient.Send(m_content, 255); //发送数据
m_conversation=m_conversation+"自己: "+m_content+"\r\n";
m_content="";
UpdateData(FALSE);
}
消息到达,此函数被启动,把套接字中的内容读到缓冲区并且显示。
void CNetclientDlg::ShowMsg()
{
char buf[255];
myclient.Receive(buf, 255);
CString msg;
msg.Format("%s", buf);
m_conversation=m_conversation+"对方: "+m_content+"\r\n";
//AfxMessageBox(msg);
UpdateData(false);
}
套接字:
网络通信编程接口。
实际上是一个指向传输提供者的句柄(指向指针(结构体指针)的指针,)。在winsock中就是通过操作该句柄来实现网络通讯和管理的。
按性质和作用的不同,可以分为三种:原始套接字,流式套接字(通信前计算机双方要建立连接。如TCP协议),和数据包套接字(提供双向数据流,如udp协议)
按函数执行的方式不同可分为:阻塞套接字(默认情况。套接字函数的执行会一直等待,直到函数调用完成。在IO操作完成之前不会将控制权交给程序,在一个线程中只能进行一项IO操作其后的IO操作必须等到正在执行的IO操作完成后才会执行)和非阻塞套接字(套接字函数的调用会立即返回将控制权交给程序)。
创建套接字的函数:SOCKET clientSock=socket(AF_INET,SOCK_STREAM,0);//创建套接字
套接字设置非阻塞模式函数:int nState=ioclsocket(clientSock,FIONBIO,&NcMD);
unsigned long nCmd;
SOCKET clientSock=socket(AF_INET,SOCK_STREAM,0);//创建套接字
if(clientSock==INVALID_SOCKET)
{return 0;}
int nState=ioclsocket(clientSock,FIONBIO,&NcMD);//设置非阻塞模式
if(nState!=0)
{
TRACE("设置套接字非阻塞模式失败");
}
对TCP/IP 套接字来说,sockaddr_in结构指定了套接字的地址,其他协议使用相似的结构
sockaddr_in local;
local.sin_family=AF_INET; // 地址家族Address family
local.sin_addr.s_addr=INADDR_ANY; // 要求使用当前主机配置的所有IP地址
local.sin_port=htons((u_short)20248); // 使用的端口
// 为套接字关联本地地址的函数是bind.。
// bind函数用在没有建立连接的套接字上,它的作用是绑定面向连接的或者无连接的套接字。
// 套接字被socket函数创建以后,存在于指定的地址家族里,但它是未命名的。
// bind函数通过安排一个本地名称到未命名的socket建立此socket的本地关联。
// 本地名称包含3个部分:主机地址、协议号(分别为UDP或TCP)和端口号。
if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
{
return 0;
}
// listen函数设置套接字进入监听状态
// 为了接受连接,首先使用socket函数创建一个套接字,然后使用bind函数将它绑定到一个本地地址,
// 再用listen函数为到达的连接指定一个backlog,最后使用accept接受请求的连接。
// 函数的第二个参数是backlog值
if(listen(server,10)!=0)
{
return 0;
}
SOCKET client;
sockaddr_in from;
int fromlen=sizeof(from);
// 下面进入无限循环
while(true)
{
char temp[512];
// accept() 将接受到了的客户连接
client=accept(server,(struct sockaddr*)&from,&fromlen);
sprintf(temp,"Your IP is %s\r\n",inet_ntoa(from.sin_addr));
// 我们简单地将这串字符发送给客户
send(client,temp,strlen(temp),0);
cout 内存块。内核对象的数据只能由系统内核来访问。应用程序无法在内存中找到哦啊这些数据结构并直接改变它们的内容。线程描述的是代码执行路径,每一个线程都关联一个线程函数。
进程:正在运行的程序实例,提供地址空间,其中包含有可执行程序和动态链接库的代码和数据。进程可以简单理解为一个容器,只是提供空间,执行程序的饿代码是由线程来实现的。线程存在于进程当中,负责执行进程地址空间的代码。当一个进程创建时,系统会自动为其创建一个线程,该线程被称为主线程。
向库模块中添加 ws2_32.lib的方法:在代码中加入:#pragma comment(lib, "WS2_32"),所有的Winsock函数都是从WS2_32.DLL导出的
// SOCKET实际上是一个unsigned int类型
响应快捷键方法:
方法一:
问题:
VC 怎么给程序设置快捷键来响应一个函数
VC 怎么给程序设置快捷键来响应一个函数?
例如我按下F1来响应 BUTTON1的函数?
回答:
对着对话框类点右键,添加虚函数PreTranslateMessage
例子如下:
BOOL CLoginDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
case VK_F1:
Onbutton1();//这里添加函数之类的
break;
default:
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
方法二
设置某个按钮为快捷键按下:
选中该button,属性,显示名后加上 &t
那么按下ALT +t 的时候,就会执行按下该按钮所对应的函数。
2010年08月14日
今天辛苦比照标准程序,终于把socket程序调通。
注意:用vc6.0环境,创建对话框程序,在创建的时候勾选上,csocket支持。
程序有两个,一个客户端程序,一个服务器端程序。
服务器端:
两个csocket对象,
mysocket m_recv; 用来接收和发送消息
mysocket m_server;用来监听连接和响应消息
mysocket 继承 CSocket,
重载两个消息函数:
void mysocket::OnAccept(int nErrorCode)
{
CSocket::OnAccept(nErrorCode);
((CMyseverDlg*)(AfxGetApp()->m_pMainWnd))->ShowAccept();
CSocket::OnAccept(nErrorCode);
}
void mysocket::OnReceive(int nErrorCode)
{
CSocket::OnReceive(nErrorCode);
((CMyseverDlg*)(AfxGetApp()->m_pMainWnd))->ShowMsg();
}
对话框类中:
消息启动m_server, 接收连接,并转嫁到m_recv
void CMyseverDlg::ShowAccept()
{
m_server.Accept(m_recv);//使连接转移到m_recv上
AfxMessageBox("Server端连接成功");
}
消息启动m_server,转嫁到m_recv接收消息,并且显示。
void CMyseverDlg::ShowMsg()
{
char buf[255];
m_recv.Receive(buf,255);
CString msg;
msg.Format("%s",buf);
m_conversation+="对方:"+msg+"\r\n";
UpdateData(false);
}
通过 m_recv 直接发送消息
void CMyseverDlg::Onsend()
{
UpdateData(true);
m_recv.Send(m_content, 255); //发送数据
m_conversation=m_conversation+"自己:"+m_content+"\r\n";
m_content="";
UpdateData(false);
}
客户端:
一个CSocket类对象
class mysocket : public CSocket(){。。。}
mysocket myclient;
myclient.Create(1001); //使用1001号端口
if(myclient.Connect(m_ip, 1000)) //连接目标IP m_ip,1000端口
重载一个系统消息函数,用于发现消息,并且启动对话框的显示;
void mysocket::OnReceive(int nErrorCode)
{
((CNetclientDlg*)(AfxGetApp()->m_pMainWnd))->ShowMsg();
CSocket::OnReceive(nErrorCode);
}
对话框
发送消息
void CNetclientDlg::Onsend()
{
UpdateData(TRUE); //更新数据,使m_msg得到当前框中文本
myclient.Send(m_content, 255); //发送数据
m_conversation=m_conversation+"自己: "+m_content+"\r\n";
m_content="";
UpdateData(FALSE);
}
消息到达,此函数被启动,把套接字中的内容读到缓冲区并且显示。
void CNetclientDlg::ShowMsg()
{
char buf[255];
myclient.Receive(buf, 255);
CString msg;
msg.Format("%s", buf);
m_conversation=m_conversation+"对方: "+m_content+"\r\n";
//AfxMessageBox(msg);
UpdateData(false);
}
套接字:
网络通信编程接口。
实际上是一个指向传输提供者的句柄(指向指针(结构体指针)的指针,)。在winsock中就是通过操作该句柄来实现网络通讯和管理的。
按性质和作用的不同,可以分为三种:原始套接字,流式套接字(通信前计算机双方要建立连接。如TCP协议),和数据包套接字(提供双向数据流,如udp协议)
按函数执行的方式不同可分为:阻塞套接字(默认情况。套接字函数的执行会一直等待,直到函数调用完成。在IO操作完成之前不会将控制权交给程序,在一个线程中只能进行一项IO操作其后的IO操作必须等到正在执行的IO操作完成后才会执行)和非阻塞套接字(套接字函数的调用会立即返回将控制权交给程序)。
创建套接字的函数:SOCKET clientSock=socket(AF_INET,SOCK_STREAM,0);//创建套接字
套接字设置非阻塞模式函数:int nState=ioclsocket(clientSock,FIONBIO,&NcMD);
unsigned long nCmd;
SOCKET clientSock=socket(AF_INET,SOCK_STREAM,0);//创建套接字
if(clientSock==INVALID_SOCKET)
{return 0;}
int nState=ioclsocket(clientSock,FIONBIO,&NcMD);//设置非阻塞模式
if(nState!=0)
{
TRACE("设置套接字非阻塞模式失败");
}
对TCP/IP 套接字来说,sockaddr_in结构指定了套接字的地址,其他协议使用相似的结构
sockaddr_in local;
local.sin_family=AF_INET; // 地址家族Address family
local.sin_addr.s_addr=INADDR_ANY; // 要求使用当前主机配置的所有IP地址
local.sin_port=htons((u_short)20248); // 使用的端口
// 为套接字关联本地地址的函数是bind.。
// bind函数用在没有建立连接的套接字上,它的作用是绑定面向连接的或者无连接的套接字。
// 套接字被socket函数创建以后,存在于指定的地址家族里,但它是未命名的。
// bind函数通过安排一个本地名称到未命名的socket建立此socket的本地关联。
// 本地名称包含3个部分:主机地址、协议号(分别为UDP或TCP)和端口号。
if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
{
return 0;
}
// listen函数设置套接字进入监听状态
// 为了接受连接,首先使用socket函数创建一个套接字,然后使用bind函数将它绑定到一个本地地址,
// 再用listen函数为到达的连接指定一个backlog,最后使用accept接受请求的连接。
// 函数的第二个参数是backlog值
if(listen(server,10)!=0)
{
return 0;
}
SOCKET client;
sockaddr_in from;
int fromlen=sizeof(from);
// 下面进入无限循环
while(true)
{
char temp[512];
// accept() 将接受到了的客户连接
client=accept(server,(struct sockaddr*)&from,&fromlen);
sprintf(temp,"Your IP is %s\r\n",inet_ntoa(from.sin_addr));
// 我们简单地将这串字符发送给客户
send(client,temp,strlen(temp),0);
cout 内存块。内核对象的数据只能由系统内核来访问。应用程序无法在内存中找到哦啊这些数据结构并直接改变它们的内容。线程描述的是代码执行路径,每一个线程都关联一个线程函数。
进程:正在运行的程序实例,提供地址空间,其中包含有可执行程序和动态链接库的代码和数据。进程可以简单理解为一个容器,只是提供空间,执行程序的饿代码是由线程来实现的。线程存在于进程当中,负责执行进程地址空间的代码。当一个进程创建时,系统会自动为其创建一个线程,该线程被称为主线程。
向库模块中添加 ws2_32.lib的方法:在代码中加入:#pragma comment(lib, "WS2_32"),所有的Winsock函数都是从WS2_32.DLL导出的
// SOCKET实际上是一个unsigned int类型
响应快捷键方法:
方法一:
问题:
VC 怎么给程序设置快捷键来响应一个函数
VC 怎么给程序设置快捷键来响应一个函数?
例如我按下F1来响应 BUTTON1的函数?
回答:
对着对话框类点右键,添加虚函数PreTranslateMessage
例子如下:
BOOL CLoginDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
case VK_F1:
Onbutton1();//这里添加函数之类的
break;
default:
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
方法二
设置某个按钮为快捷键按下:
选中该button,属性,显示名后加上 &t
那么按下ALT +t 的时候,就会执行按下该按钮所对应的函数。