dev-cpp下写socket

diyemei 2007-04-28 07:56:14
dev-cpp的头文件中只有winsock.h和winsock2.h,但我想用巴克力socket,包含以上两个文件后,能写吗?具体怎么用
...全文
405 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
jixingzhong 2007-04-28
  • 打赏
  • 举报
回复
链接中讲的比较详细,楼主自己看看,不需要拷贝过来贴上了把?
diyemei 2007-04-28
  • 打赏
  • 举报
回复
太深奥了吧.我是初学者啊,简单点的讲具体点就行了啊
jixingzhong 2007-04-28
  • 打赏
  • 举报
回复
http://blog.vckbase.com/arong/archive/2005/10/31/14340.html

看看这个链接
jixingzhong 2007-04-28
  • 打赏
  • 举报
回复
找的看看吧!
一、简介
WINDOWS SOCKETS 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又进行了新的扩充。这些扩充主要是提供了一些异步函数,并增加了符合WINDOWS消息驱动特性的网络事件异步选择机制。
WINDOWS SOCKETS由两部分组成:开发组件和运行组件。
开发组件:WINDOWS SOCKETS 实现文档、应用程序接口(API)引入库和一些头文件。
运行组件:WINDOWS SOCKETS 应用程序接口的动态链接库(WINSOCK.DLL)。


二、主要扩充说明

1、异步选择机制:
WINDOWS SOCKETS 的异步选择函数提供了消息机制的网络事件选择,当使用它登记网络事件发生时,应用程序相应窗口函数将收到一个消息,消息中指示了发生的网络事件,以及与事件相关的一些信息。
WINDOWS SOCKETS 提供了一个异步选择函数 WSAAsyncSelect(),用它来注册应用程序感兴趣的网络事件,当这些事件发生时,应用程序相应的窗口函数将收到一个消息。
函数结构如下:

int PASCAL FAR WSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg,long lEvent);
参数说明:
hWnd:窗口句柄
wMsg:需要发送的消息
lEvent:事件(以下为事件的内容)
值: 含义:
FD_READ 期望在套接字上收到数据(即读准备好)时接到通知
FD_WRITE 期望在套接字上可发送数据(即写准备好)时接到通知
FD_OOB 期望在套接字上有带外数据到达时接到通知
FD_ACCEPT 期望在套接字上有外来连接时接到通知
FD_CONNECT 期望在套接字连接建立完成时接到通知
FD_CLOSE 期望在套接字关闭时接到通知
例如:我们要在套接字读准备好或写准备好时接到通知,语句如下: rc=WSAAsyncSelect(s,hWnd,wMsg,FD_READ|FD_WRITE);
如果我们需要注销对套接字网络事件的消息发送,只要将 lEvent 设置为0

2、异步请求函数
在 Berkeley Sockets 中请求服务是阻塞的,WINDOWS SICKETS 除了支持这一类函数外,还增加了相应的异步请求函数(WSAAsyncGetXByY();)。
3、阻塞处理方法
WINDOWS SOCKETS 为了实现当一个应用程序的套接字调用处于阻塞时,能够放弃CPU让其它应用程序运行,它在调用处于阻塞时便进入一个叫“HOOK”的例程,此例程负责接收和分配WINDOWS消息,使得其它应用程序仍然能够接收到自己的消息并取得控制权。
WINDOWS 是非抢先的多任务环境,即若一个程序不主动放弃其控制权,别的程序就不能执行。因此在设计 WINDOWS SOCKETS 程序时,尽管系统支持阻塞操作,但还是反对程序员使用该操作。但由于 SUN 公司下的 Berkeley Sockets 的套接字默认操作是阻塞的,WINDOWS 作为移植的 SOCKETS 也不可避免对这个操作支持。
在 WINDOWS SOCKETS 实现中,对于不能立即完成的阻塞操作做如下处理:DLL初始化→循环操作。在循环中,它发送任何 WINDOWS 消息,并检查这个 WINDOWS SOCKETS 调用是否完成,在必要时,它可以放弃CPU让其它应用程序执行(当然使用超线程的CPU就不会有这个麻烦了^_^)。我们可以调用 WSACancelBlockingCall() 函数取消此阻塞操作。
在 WINDOWS SOCKETS 中,有一个默认的阻塞处理例程 BlockingHook() 简单地获取并发送 WINDOWS 消息。如果要对复杂程序进行处理,WINDOWS SOCKETS 中还有 WSASetBlockingHook() 提供用户安装自己的阻塞处理例程能力;与该函数相对应的则是 SWAUnhookBlockingHook(),它用于删除先前安装的任何阻塞处理例程,并重新安装默认的处理例程。请注意,设计自己的阻塞处理例程时,除了函数 WSACancelBlockingHook() 之外,它不能使用其它的 WINDOWS SOCKETS API 函数。在处理例程中调用 WSACancelBlockingHook()函数将取消处于阻塞的操作,它将结束阻塞循环。

4、出错处理
WINDOWS SOCKETS 为了和以后多线程环境(WINDOWS/UNIX)兼容,它提供了两个出错处理函数来获取和设置当前线程的最近错误号。(WSAGetLastEror()和WSASetLastError())

5、启动与终止
使用函数 WSAStartup() 和 WSACleanup() 启动和终止套接字。


三、WINDOWS SOCKETS 网络程序设计核心

我们终于可以开始真正的 WINDOWS SOCKETS 网络程序设计了。不过我们还是先看一看每个 WINDOWS SOCKETS 网络程序都要涉及的内容。让我们一步步慢慢走。

1、启动与终止
在所有 WINDOWS SOCKETS 函数中,只有启动函数 WSAStartup() 和终止函数 WSACleanup() 是必须使用的。
启动函数必须是第一个使用的函数,而且它允许指定 WINDOWS SOCKETS API 的版本,并获得 SOCKETS的特定的一些技术细节。本结构如下: int PASCAL FAR WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
其中 wVersionRequested 保证 SOCKETS 可正常运行的 DLL 版本,如果不支持,则返回错误信息。
我们看一下下面这段代码,看一下如何进行 WSAStartup() 的调用 WORD wVersionRequested;// 定义版本信息变量
WSADATA wsaData;//定义数据信息变量
int err;//定义错误号变量
wVersionRequested = MAKEWORD(1,1);//给版本信息赋值
err = WSAStartup(wVersionRequested, &wsaData);//给错误信息赋值
if(err!=0)
{
return;//告诉用户找不到合适的版本
}
//确认 WINDOWS SOCKETS DLL 支持 1.1 版本
//DLL 版本可以高于 1.1
//系统返回的版本号始终是最低要求的 1.1,即应用程序与DLL 中可支持的最低版本号
if(LOBYTE(wsaData.wVersion)!= 1|| HIBYTE(wsaData.wVersion)!=1)
{
WSACleanup();//告诉用户找不到合适的版本
return;
}
//WINDOWS SOCKETS DLL 被进程接受,可以进入下一步操作
关闭函数使用时,任何打开并已连接的 SOCK_STREAM 套接字被复位,但那些已由 closesocket() 函数关闭的但仍有未发送数据的套接字不受影响,未发送的数据仍将被发送。程序运行时可能会多次调用 WSAStartuo() 函数,但必须保证每次调用时的 wVersionRequested 的值是相同的。

2、异步请求服务
WINDOWS SOCKETS 除支持 Berkeley Sockets 中同步请求,还增加了了一类异步请求服务函数 WSAAsyncGerXByY()。该函数是阻塞请求函数的异步版本。应用程序调用它时,由 WINDOWS SOCKETS DLL 初始化这一操作并返回调用者,此函数返回一个异步句柄,用来标识这个操作。当结果存储在调用者提供的缓冲区,并且发送一个消息到应用程序相应窗口。常用结构如下:
HANDLE taskHnd;
char hostname="rs6000";
taskHnd = WSAAsyncBetHostByName(hWnd,wMsg,hostname,buf,buflen);
需要注意的是,由于 Windows 的内存对像可以设置为可移动和可丢弃,因此在操作内存对象是,必须保证 WIindows Sockets DLL 对象是可用的。
3、异步数据传输
使用 send() 或 sendto() 函数来发送数据,使用 recv() 或recvfrom() 来接收数据。Windows Sockets 不鼓励用户使用阻塞方式传输数据,因为那样可能会阻塞整个 Windows 环境。下面我们看一个异步数据传输实例:
假设套接字 s 在连接建立后,已经使用了函数 WSAAsyncSelect() 在其上注册了网络事件 FD_READ 和 FD_WRITE,并且 wMsg 值为 UM_SOCK,那么我们可以在 Windows 消息循环中增加如下的分支语句:

case UM_SOCK:
switch(lParam)
{
case FD_READ:
len = recv(wParam,lpBuffer,length,0);
break;
case FD_WRITE:
while(send(wParam,lpBuffer,len,0)!=SOCKET_ERROR)
break;
}
break;

4、出错处理
Windows 提供了一个函数来获取最近的错误码 WSAGetLastError(),推荐的编写方式如下: len = send (s,lpBuffer,len,0);
of((len==SOCKET_ERROR)&&(WSAGetLastError()==WSAWOULDBLOCK)){...}
walkingstick 2007-04-28
  • 打赏
  • 举报
回复
mark~~~~~~~~
sinovoice 2007-04-28
  • 打赏
  • 举报
回复
我在vc2003下测试通过了!你试试
sinovoice 2007-04-28
  • 打赏
  • 举报
回复
刚好前几天我看到一个人写的。供您参考一下。
//今天自己实现了C++的socket编程,分Client Server端, 在Dev C++下编译通过。
/************SocketClient************************/
/*************Add "-lwsock32" (without the quotes) to the linker box under Project->Project Options-linker options.*********************/

#include

#include
//#include //this can be replaced by WS2_32.lib
#pragma comment (lib,"WS2_32.lib")
#define USERPORT 8000
main(int argc,char *argv[])
{
char buf[128];
SOCKET sclient;
struct sockaddr_in server;
int namelen,pklen;
int status,ret;
char szmessage[128];
WSADATA wsd;
char ch;
char * ipaddr;
printf("Please ensure that the SocketServer.exe is running in the server! \n ");
if (argc<2){
printf("Please input the ip address(127.0.0.1).Default:202.127.205.185\n");
scanf("%s",ipaddr);
if (sizeof(ipaddr)<7) ipaddr= "202.127.205.185" ; //this may be replaced by argv[1]
printf("\n");
}
else if (argc=2)
{ ipaddr= argv[1];
}
else
{ perror("params too much!");
exit(1);}
if((status=WSAStartup(MAKEWORD(2,2),&wsd))!=0)
{
perror("wsastartup() failed:");
exit(1);
}
if((sclient=socket(AF_INET,SOCK_STREAM,0))< 0)
{
perror("socket failed :");
exit(1);
}
ZeroMemory(&server,sizeof(server));
ZeroMemory(szmessage,sizeof(szmessage));
server.sin_family=AF_INET;
server.sin_port=htons(USERPORT);

server.sin_addr.s_addr=inet_addr(ipaddr);
if(connect(sclient,(struct sockaddr
*)&server,sizeof(server))<0)
{ printf("%s",ipaddr);
perror("connect failed :");
printf("%d",WSAGetLastError());

exit(3);
}
else
{ printf("%s%s",ipaddr," connect OK!\n");
}
namelen=sizeof(sclient);


while(1)
{

ZeroMemory(szmessage,sizeof(szmessage));
printf("Press q to exit or input string(size<128) sent to server: ",szmessage);

scanf("%s",szmessage);
printf("\n");
if (szmessage=="q") break;
// send(sclient,szmessage,sizeof(szmessage),0);


if(send(sclient,szmessage,sizeof(szmessage),0)<0)
{
perror("send() failed:");
break;
}

printf("send return success!\n context is %s \n",szmessage);
Sleep(10);


}


closesocket(sclient);
WSACleanup();
printf("server ended successfully!Input any key to exit\n");
scanf("%c",&ch);
return 0;
}

/***************SocketServer*******************/

/* Add "-lwsock32" (without the quotes) to the linker box under Project->Project Options->linker options.
If you have not set up a project, you will have to do that first. Go to File->New->Project->Empty Project. Then add your files by using Project->Add to Project.
If you want to link with other windows libraries you can use the same syntax. For example, "-lgdi32 -ladvapi32" will link to gdi32.lib and advapi32.lib.
*/
#include
#include
#pragma comment (lib,"WS2_32.lib")
//#include

main(int argc,char *argv[])
{
int USERPORT=8000 ;
char * HOST_IP_ADDR;
if (argc<2)
{
printf("Please Input the ipaddress of the server(127.0.0.1)Default:202.127.205.185\n");
scanf("%s",HOST_IP_ADDR);
if (sizeof(HOST_IP_ADDR)<7) HOST_IP_ADDR="202.127.205.185";
}else
{HOST_IP_ADDR=argv[1];
}
char buf[128];
SOCKET s,ns;
struct sockaddr_in client;
struct sockaddr_in server;
int namelen,pklen;
int status;
WSADATA wsd;
printf("The SocketServer is running now--%s\n",HOST_IP_ADDR);
printf("Waiting for inputs from Client\n");
if((status=WSAStartup(MAKEWORD(2,2),&wsd))!=0)
{
perror("wsastartup() failed:");
exit(1);
}
if((s=socket(AF_INET,SOCK_STREAM,0))< 0)
{
perror("socket failed :");
exit(1);
}
ZeroMemory(&server,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(USERPORT);
server.sin_addr.s_addr=htons(INADDR_ANY);
if(bind(s,(struct sockaddr *)&server,sizeof(server))<0)
{
perror("bind() failed:");
exit(2);
}
if(listen(s,4)!=0)
{
perror("listen()failed :");
exit(3);
}
while(1)
{
namelen=sizeof(client);
if((ns=accept(s,(struct
sockaddr*)&client,&namelen))==-1)
{
perror("accept()failed:");
exit(4);
}
printf("accept() successful!\n");
for(;;)
{
if((pklen=recv(ns,buf,128,0))<0)
{
perror("recv() failed:");
exit(5);
}
else
if(pklen==0)
{
printf("recv():return FAILED,connected is shut
down");
break;
}
else
printf("recv():return success,packet length=%d
context is %s\n",pklen,buf);

Sleep(1);

}
}
closesocket(ns);
closesocket(s);
printf("server ended successfully\n");
}

64,654

社区成员

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

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