创建套接字相对来说比较耗时.
解决方案 »
- SetFocus 和SendMessage 我该用哪个?(子窗口接收鼠标滚轮事件)
- 如何把不同的IP连通在局域网下。
- 请教关于memcpy用法
- 曲线重叠时,只显示离观察者较近的曲线,后面曲线重叠部分不可见
- CTreeCtrl中TVIS_SELECTED,选中与去掉选中
- 线程与事件
- cursor一问?
- 急需解决的socket的问题, 高手请进。
- 怎样调用windows命令
- MFC中用jmail组件删除邮件问题 DeleteSingleMessage(i)语句不能删除邮箱收件箱的邮件
- 函数内部加了CArray<CPoint, CPoint> pointArrayStart;编译不过,为什么?
- 高分求购哈密顿环问题的穷尽搜索算法(进者有分啊,在线等) 多谢,多谢
一个连接就要用一个套接字来维持啊,
connect时会生成这个套接字,而原来的套接字还在监听,
你要使用这个新的套接字来通讯,完了删掉就行了
while(true)
{
socket2=accept() //得到连接上的client socket
}
{ return;}iRet=connect(hSocket,.....)if(iRet==SOCKET_ERROR)
{ return;}//到这个地方hSocket已经连接成功了, 可是我想断掉他,让他再做别的事情,就象一个CDatabase
// 可以连接到一个数据库,然后close,然后再连接导另外一个数据库
// 我不想closesocket,再wsasocket(...)一个新的。我想重新利用。.....(对socket的一些操作?????应该做什么操作)bind(hSocket....); //如果没有操作,这儿肯定会出错的。我试过几种方法,都不行。像shutdown,wsasenddisconnect, 指定了断开连接的tranmitfile。都不行listen(hSocket,..);
closesocket,就相当于delete 释放资源了,能不能不释放资源只初始化?to iicup(双杯献酒)我不是想又监听又连接,我是想连接完毕后,再把它初始化,然后再去监听.
等待有新的套接字的需求的时候,就从链表中取出一个socket,去使用.
进行的操作,可能是connect(hSocket,...) 也可能是lpfnAcceptEx(hSocket,....)
,也可能是绑定一个另外的端口.http://community.csdn.net/Expert/topic/3657/3657040.xml?temp=.7058069
其实Accept后产生了一个新的套接字,与Accept的连接关联
原Listen的套接字继续Listen
所以不用重新创建套接字,绑定
原侦听中的套接字依然继续侦听
服务器都是这样实现的
与是否closesocket无关
closesocket后照样socket变量照样可以存在于队列中
下次Accept或Connect得到的socket存于在队列中的socket变量就好但是不关闭socket,会消耗系统资源.
SOCKET sListenSocket,
SOCKET sAcceptSocket,
PVOID lpOutputBuffer,
DWORD dwReceiveDataLength,
DWORD dwLocalAddressLength,
DWORD dwRemoteAddressLength,
LPDWORD lpdwBytesReceived,
LPOVERLAPPED lpOverlapped
);我想需要的就是传给acceptex的sAcceptSocket,不是每次都用wsasocket(...)建立的.
而是,所有的可用套接字都存在一个链表中.acceptex之前,就从链表中取一个.上面说的 当然谁都会了,有不会的吗?最重要的问题在这儿,当web服务器与客户端的连接断了之后,这个sAcceptSocket怎么办????方法1: closeSocket? 这个任何人都会.方法2: 初始化到刚创建的状态,放入可用队列中,等待下次客户端连上来时再用怎么初始化????????????????????????????????????????????????????????????????????????????
可是我不想closesocket她,我想留下来为以后备用,就不用再wsasocket(..)了可是经过什么处理,才能让这个陶介子达到最初的刚被创建的状态,这样我才能再用到别的地方阿?
做一个真正程序员,我们更应该关心我们的应用效率。如果你真的很关心你的程序的效率和操作系统的核心效率,我建议多看看操作系统的核心技术,不管是Windows还是Unix、Linux、VXWorks、Nucleus等等,都有相关的资料介绍,Linux的源码很容易得到,/usr/src/里面有的是,kernel,net下面包含了大部分的网络代码,现在流行的Web服务aparche的源码网上有的是。就TCP/IP应用来说你可以参考一下TCP/IP详解卷一:协议,卷二:实现(有源码分析),卷三:TCP事务以及(各种)应用。等你真正熟习了它的原理,你就会对你的问题得到答案,回头也就不会再提出类似的问题了。也就是说,现在有很多人都明白了你“从头到尾”的意思,但没有人能够对你的需求提出解决方案。
是怎么出出里的,假如一秒钟有5000个访问者,那程序就要创建5000的陶介子,还要销毁5000个套介子。
怎么我一问,就没有人回答了。
当你采用accept响应客户的请求时,它一定会给你一个由核心TCP/IP处理完连接后的socket(你无法干预),如果你不接收这个套接子,那么它就被你丢失在你的进程中,直到你的进程消失,核心才有机会将该丢失的套接子资源收回。除非你避开socket的API调用而自己来实现TCP连接的代码实现。
至于你所说的:假如一秒钟有5000个访问者,那程序就要创建5000的陶介子,还要销毁5000个套介子。
不错。当你浏览网站时,经常会遇到“服务器忙,无法连接”,往往就是访问的客户太多而暂时无法再给你提高访问。
我接受客户端的请求时,可以不用accept函数,而是用acceptex,这样就可以自己控制通信套接字的创建了to click2004:
如果系统没有缓冲池的话,肯定有程序实现的,你再找找,我英语不好,国外站点肯定有解决方案.
楼主你的出发点本来是很好,不过这样做好象行不通,就象你用CreateFile创建了一个文件句柄,下次还想用这个句柄去打开另一个文件,道理是一样的。SOCKET象句柄一样只是一个值,一个指向某个内核对象的资源符号而已。
ms-help://MS.MSDNQTR.2004OCT.1033/winsock/winsock/acceptex_2.htm
Requirements系统需求
Client: Requires Windows XP, Windows 2000 Professional, or Windows NT Workstation 3.51 and later.
Server: Requires Windows Server 2003, Windows 2000 Server, or Windows NT Server 3.51 and later.
Header: Declared in Mswsock.h.
Library: Use Mswsock.lib.
See Also
也就是说,你也改变一个端口的连接行为,就必须把那个端口弄回到初始状态,否则对它的一切操作都是非法的。
accetpex的目的是
1 非阻塞
2 在客户端没有连接进来之前创建好通信套接字,并把它放入接受请求包中投递出去.
3 同时投递1000个acceptex,可以同时接受1000个连接.
否则,假如系统能预先接纳50个,只能处理完50个,再处理下50个.这就要在客户端等待的时候创建会话资源.
linux的close,win的closesocket 之后,资源已经释放了,不能再用了.
#include "winsock2.h"
#include "mswsock.h"void main() {
//----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
HANDLE hCompPort;
LPFN_ACCEPTEX lpfnAcceptEx = NULL;
GUID GuidAcceptEx = WSAID_ACCEPTEX;
WSAOVERLAPPED olOverlap;
SOCKET ListenSocket, AcceptSocket;
sockaddr_in service;
char lpOutputBuf[1024];
int outBufLen = 1024;
DWORD dwBytes; //----------------------------------------
// Initialize Winsock
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if( iResult != NO_ERROR )
printf("Error at WSAStartup\n"); //----------------------------------------
// Create a handle for the completion port
hCompPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, (u_long)0, 0 ); //----------------------------------------
// Create a listening socket
ListenSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (ListenSocket == INVALID_SOCKET) {
printf("Error at socket(): ListenSocket\n");
WSACleanup();
return;
} //----------------------------------------
// Associate the listening socket with the completion port
CreateIoCompletionPort((HANDLE)ListenSocket, hCompPort, (u_long)0, 0); //----------------------------------------
// Bind the listening socket to the local IP address
// and port 27015
hostent* thisHost;
char* ip;
u_short port;
port = 27015;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list); service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip); service.sin_port = htons(port); if ( bind( ListenSocket,(SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
printf("bind failed\n");
closesocket(ListenSocket);
return;
} //----------------------------------------
// Start listening on the listening socket
if (listen( ListenSocket, 100 ) == SOCKET_ERROR) {
printf("error listening\n");
}
printf("Listening on address: %s:%d\n", ip, port); //----------------------------------------
// Load the AcceptEx function into memory using WSAIoctl.
// The WSAIoctl function is an extension of the ioctlsocket()
// function that can use overlapped I/O. The function's 3rd
// through 6th parameters are input and output buffers where
// we pass the pointer to our AcceptEx function. This is used
// so that we can call the AcceptEx function directly, rather
// than refer to the Mswsock.lib library.
WSAIoctl(ListenSocket,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&GuidAcceptEx,
sizeof(GuidAcceptEx),
&lpfnAcceptEx,
sizeof(lpfnAcceptEx),
&dwBytes,
NULL,
NULL); //----------------------------------------
// Create an accepting socket
AcceptSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (AcceptSocket == INVALID_SOCKET) {
printf("Error creating accept socket.\n");
WSACleanup();
return;
} //----------------------------------------
// Empty our overlapped structure and accept connections.
memset(&olOverlap, 0, sizeof(olOverlap)); lpfnAcceptEx(ListenSocket,
AcceptSocket,
lpOutputBuf,
outBufLen - ((sizeof(sockaddr_in) + 16) * 2),
sizeof(sockaddr_in) + 16,
sizeof(sockaddr_in) + 16,
&dwBytes,
&olOverlap); //----------------------------------------
// Associate the accept socket with the completion port
CreateIoCompletionPort((HANDLE)AcceptSocket, hCompPort, (u_long)0, 0); //----------------------------------------
// Continue on to use send, recv, TransmitFile(), etc.,.
...}
acceptex不是非阻塞的难道是阻塞的吗?虽然他不是真正的接受一个连接请求,
但是相对与阻塞的accept和阻塞的wsaaccpet来说,accpetex不是绝对是非阻塞函数吗?