windows8系统下载的MajVer和MinVer是多少

Oracle Code Library
Find Or Post Oracle Jobs
Oracle Discussion & Chat
&Search the Reference Library pages: &
Oracle DBMS_PROFILER
Version 10.2
Installation Instructions
{ORACLE_HOME}/rdbms/admin/dbmspbp.sql
-- also review
{ORACLE_HOME}/plsql/demo/profsum.sql
First Available
Return values from DBMS_PROFILER functions
BINARY_INTEGER
error_param
BINARY_INTEGER
error_version
BINARY_INTEGER
major_version
BINARY_INTEGER
minor_version
BINARY_INTEGER
BINARY_INTEGER
Dependencies
DBMS_PROFILER_LIB
Exceptions
Exception Name
Error Code
profiler_error
Parameter or I/O error
version_mismatch
Incorrect profiler version for database
System Privileges
GRANT create session TO
&schema_name&;
GRANT create procedure TO &schema_name&;
GRANT create sequence TO &schema_name&;
GRANT create table TO &schema_name&;
GRANT create view TO &schema_name&;
GRANT create session TO
GRANT create procedure TO
GRANT create sequence TO
GRANT create table TO
GRANT create view TO
FLUSH_DATA
Flushes the Profiler buffer
to the Profiler tables
Overload 1
dbms_profiler.flush_data RETURN BINARY_INTEGER;
See PAUSE_PROFILER Demo
Overload 2
dbms_profiler.flush_
dbms_profiler.flush_data
GET_VERSION
Returns the Profiler API
dbms_profiler.get_version(
major OUT BINARY_INTEGER,
minor OUT BINARY_INTEGER);
set serveroutput on
&majver BINARY_INTEGER;
&minver BINARY_INTEGER;
& dbms_profiler.get_version(majver, minver);
& dbms_output.put_line('Major: ' || TO_CHAR(majver));
& dbms_output.put_line('Minor: ' || TO_CHAR(minver));
INTERNAL_VERSION_CHECK
Returns the Profiler
package& version for compatibility verification
dbms_profiler.internal_version_check RETURN
BINARY_INTEGER;
dbms_profiler.internal_version_check
PAUSE_PROFILER
Pauses Profiler data
collection
Overload 1
dbms_profiler.pause_profiler RETURN
BINARY_INTEGER;
&i PLS_INTEGER;
& i := dbms_profiler.flush_data;
& i := dbms_profiler.pause_profiler;
& i := dbms_profiler.resume_profiler;
Overload 2
dbms_profiler.pause_
dbms_profiler.pause_profiler
RESUME_PROFILER
Restarts Profiler data
collection
Overload 1
dbms_profiler.resume_profiler RETURN
BINARY_INTEGER;
See PAUSE_PROFILER Demo
Overload 2
dbms_profiler.resume_
dbms_profiler.resume_profiler
ROLLUP_RUN
Roll up and calculate the
total time usage for all units that have been part of a run
dbms_profiler.rollup_run(run_number IN
CREATE OR REPLACE PROCEDURE proc1 IS
VARCHAR2(5);
& FOR i IN 1..100
&&& SELECT dummy INTO vd FROM
& END LOOP;
END proc1;
&v_run NUMBER;
& dbms_profiler.start_profiler('test', 'test1', v_run);
& dbms_profiler.stop_profiler;
& dbms_profiler.rollup_run(v_run);
ROLLUP_UNIT
Roll up and calculate the
total time usage for a specific unit that has been part of a run
dbms_profiler.rollup_unit(
run_number IN NUMBER,
unit&&&&&& IN NUMBER);
-- executes the
following code
UPDATE plsql_profiler_units
SET total_time = (
& SELECT SUM(total_time)
& FROM plsql_profiler_data
& WHERE runid = run_number
& AND unit_number = unit);
FROM plsql_profiler_
exec dbms_profiler.rollup_unit(8, 3);
START_PROFILER
Start Profiler data collection
in the current session
Overload 1
dbms_profiler.start_profiler(
run_comment& IN& VARCHAR2 := SYSDATE,
run_comment1 IN& VARCHAR2 := '',
run_number&& OUT BINARY_INTEGER)
RETURN BINARY_INTEGER;
Overload 2
dbms_profiler.start_profiler(
run_comment& IN& VARCHAR2 := SYSDATE,
run_comment1 IN& VARCHAR2 := '',
run_number&&
OUT BINARY_INTEGER);
Overload 3
dbms_profiler.start_profiler(
run_comment& IN VARCHAR2 := SYSDATE,
run_comment1 IN VARCHAR2 := '')
RETURN BINARY_INTEGER;
Overload 4
dbms_profiler.start_profiler(
un_comment&& IN VARCHAR2 := SYSDATE,
run_comment1 IN VARCHAR2 := '');
See demo below
STOP_PROFILER
Stop Profiling
Overload 1
dbms_profiler.stop_profiler RETURN
BINARY_INTEGER;
Overload 2
dbms_profiler.stop_
See demo below
Non-Oracle
Preparation as SYS
GRANT create procedure TO
GRANT create sequence TO
GRANT create view TO
@?
dbms\admin\profload.sql
Preparation as UWCLASS
@?
dbms\admin\proftab.sql
@?\plsql\demo\profrep.sql &-- not in 11g
Procedure To Empty Profiler Tables
Between Runs
CREATE OR REPLACE PROCEDURE
profreset IS
&&DELETE FROM plsql_profiler_
&&DELETE FROM plsql_profiler_
&&DELETE FROM plsql_profiler_
DBMS_Profiler Report
Save in c: emp or equivalent
Load Demo File
Save in c: emp or equivalent
Demo Procedure
Preparations
Comma To Table Procedure Demo Tables
CREATE TABLE sources_import (
sourceno& VARCHAR2(10),
sizeno&&& VARCHAR2(10),
status&&& VARCHAR2(10),
latitude& VARCHAR2(10),
longitude VARCHAR2(10),
testfor&& VARCHAR2(15));
CREATE GLOBAL TEMPORARY TABLE gtt_c2t (
readline VARCHAR2(200))
ON COMMIT DELETE ROWS;
load_sources_import procedure
CREATE OR REPLACE PROCEDURE load_sources_import
&ProcName&& VARCHAR2(30) := 'load_sources_import';
&MyErrm&&&& VARCHAR2(250);
&vFileName& VARCHAR2(30) := 'sources.txt';
&vLoc&&&& & VARCHAR2(20) := 'CTEMP';
&v_InHandle utl_file.file_
&vNewLine&& VARCHAR2(100);
&vLineNo&&& PLS_INTEGER;
&Comma1&&&& PLS_INTEGER;
&Comma2&&&& PLS_INTEGER;
&Comma3&&&& PLS_INTEGER;
&Comma4&&&& PLS_INTEGER;
&Comma5&&&& PLS_INTEGER;
&Fld1&&&&&& sources_import.sourceno%TYPE;
&Fld2&&&&&& sources_import.sizeno%TYPE;
&Fld3&&&&&& sources_import.status%TYPE;
&Fld4&&&&&&
sources_import.latitude%TYPE;
&Fld5&&&&&&
sources_import.longitude%TYPE;
&Fld6&&&&&& sources_import.testfor%TYPE;
&NoFileToLoad EXCEPTION;
&&& v_InHandle := utl_file.fopen(vLoc, vFileName, 'r');
&&& vLineNo := 1;
&&&&& BEGIN
&&&&&&& utl_file.get_line(v_InHandle,
vNewLine);
&&&&& EXCEPTION
&&&&&&& WHEN NO_DATA_FOUND THEN
&&&&&&&&& EXIT;
&&&&& END;
&&&&& IF vLineNo & 1 THEN
&&&&&&& vNewLine := TRANSLATE(vNewLine, 'A''', 'A');
&&&&&&& Comma1 := INSTR(vNewLine, ',', 1,1);
&&&&&&& Comma2 := INSTR(vNewLine, ',', 1,2);
&&&&&&& Comma3 := INSTR(vNewLine, ',', 1,3);
&&&&&&& Comma4 := INSTR(vNewLine, ',', 1,4);
&&&&&&& Comma5 := INSTR(vNewLine, ',', 1,5);
&&&&&&& Fld1 := SUBSTR(vNewLine,1,Comma1-1);
&&&&&&& Fld2 := SUBSTR(vNewLine, Comma1+1, Comma2-Comma1-1);
&&&&&&& Fld3 := SUBSTR(vNewLine, Comma2+1, Comma3-Comma2-1);
&&&&&&& Fld4 := SUBSTR(vNewLine, Comma3+1, Comma4-Comma3-1);
&&&&&&& Fld5 := SUBSTR(vNewLine, Comma4+1, Comma5-Comma4-1);
&&&&&&& Fld6 := SUBSTR(vNewLine,Comma5+1);
&&&&&&& INSERT INTO sources_import
&&&&&&& (sourceno, sizeno, status, latitude, longitude, testfor)
&&&&&&& VALUES
&&&&&&& (Fld1, Fld2, Fld3, Fld4, Fld5, Fld6);
&&&&& ELSE
&&&&&&& vLineNo := 2;
&&&&& END IF;
&&& END LOOP;
&&& COMMIT;
&&& utl_file.fclose(v_InHandle);
& EXCEPTION
&&& WHEN utl_file.invalid_mode THEN
&&&&& RAISE_APPLICATION_ERROR (-20051, 'Invalid Option');
&&& WHEN utl_file.invalid_path THEN
&&&&& RAISE_APPLICATION_ERROR (-20052, 'Invalid Path');
&&& WHEN utl_file.invalid_filehandle THEN
&&&&& RAISE_APPLICATION_ERROR (-20053, 'Invalid
Filehandle');
&&& WHEN utl_file.invalid_operation THEN
&&&&& RAISE_APPLICATION_ERROR (-20054, 'Invalid operation');
&&& WHEN utl_file.read_error THEN
&&&&& RAISE_APPLICATION_ERROR (-20055, 'Read Error');
&&& WHEN utl_file.internal_error THEN
&&&&& RAISE_APPLICATION_ERROR (-20057, 'Internal Error');
&&& WHEN OTHERS THEN
&&&&& RAISE;
& WHEN NoFileToLoad THEN
&&& dbms_output.put_line('No File To Load Was Found');
& WHEN OTHERS THEN
&&& MyErrm := SQLERRM;
&&& dbms_output.put_line(MyErrm);
END load_sources_
Comma To Table Procedure
CREATE OR REPLACE PROCEDURE c2t_demo IS
&my_table dbms_utility.uncl_array;
&cnt&&&&&&BINARY_INTEGER;
&c_string VARCHAR2(250);
&CURSOR t_cur IS
&SELECT readline
&FROM gtt_c2t;
&t_rec t_cur%ROWTYPE;
&&& FETCH t_cur INTO t_
&&& EXIT WHEN t_cur%NOTFOUND;
&&& -- move the value from the cursor to the VARCHAR2 variable
&&& c_string := t_rec.
&&& -- use the built-in package to break it up
&&& ma_to_table(c_string,
cnt, my_table);
&&& -- use TRANSLATE to remove the single and double quotes
&&& my_table(1) := TRANSLATE(my_table(1), '1&''', '1');
&&& my_table(2) := TRANSLATE(my_table(2), '1&''', '1');
&&& my_table(3) := TRANSLATE(my_table(3), '1&''', '1');
&&& my_table(4) := TRANSLATE(my_table(4), '1&''', '1');
&&& my_table(5) := TRANSLATE(my_table(5), '1&''', '1');
&&& my_table(6) := TRANSLATE(my_table(6), '1&''', '1');
&&& INSERT INTO sources_import
&&& (sourceno, sizeno, status,
&&& latitude, longitude, testfor)
&&& VALUES
&&& (my_table(1), my_table(2), my_table(3),
&&& my_table(4), my_table(5), my_table(6));
& END LOOP;
& CLOSE t_
First Procedure To Load
Intermediary Table And
Replace Single Quotes
With Double Quotes
CREATE OR REPLACE PROCEDURE load_c2t_test IS
&vProcName&&VARCHAR2(30) := 'load_t2c_test';
&ErrMsg&&&&&VARCHAR2(250);
&vFileName&&VARCHAR2(30) := 'sources.txt';
&vLoc&&&&&& VARCHAR2(20) := 'CTEMP';
&vNewLine&&&VARCHAR2(65);
&vFirstLine&PLS_INTEGER := 0;
&StartTime&&PLS_INTEGER;
&vInHandle&&utl_file.file_
& StartTime := dbms_utility.get_
& vInHandle := utl_file.fopen(vLoc, vFileName, 'r');
&&&&& utl_file.get_line(vInHandle, vNewLine);
&&& EXCEPTION
&&&&& WHEN NO_DATA_FOUND THEN
&&&&&&& EXIT;
&&& -- find location of the delimiting commas
&&&&& IF vFirstLine && 1 THEN
&&&&&&& INSERT INTO gtt_c2t
&&&&&&& (readline)
&&&&&&& VALUES
&&&&&&& (vNewLine);
&&&&& END IF;
&&&&EXCEPTION
&&&&& WHEN OTHERS THEN
&&&&&&& RAISE;
&&END LOOP;
&&-- close the text file
&&utl_file.fclose(vInHandle);
& DELETE FROM gtt_c2t
& WHERE readline LIKE '%SOURCENO%';
& UPDATE gtt_c2t
& SET readline = TRANSLATE(readline, 'A''', 'A&');
& c2t_& -- 2nd procedure that parses record
& WHEN utl_file.invalid_mode THEN
&&& RAISE_APPLICATION_ERROR(-20051, 'Invalid Option');
& WHEN utl_file.invalid_path THEN
&&& RAISE_APPLICATION_ERROR(-20052, 'Invalid Path');
& WHEN utl_file.invalid_filehandle THEN
&&& RAISE_APPLICATION_ERROR(-20053, 'Invalid Filehandle');
& WHEN utl_file.invalid_operation THEN
&&& RAISE_APPLICATION_ERROR(-20054, 'Invalid operation');
& WHEN utl_file.read_error THEN
&&& RAISE_APPLICATION_ERROR(-20055, 'Read Error');
& WHEN utl_file.internal_error THEN
&&& RAISE_APPLICATION_ERROR(-20057, 'Internal Error');
& WHEN OTHERS THEN
&&& RAISE;
END load_c2t_
Procedure utilizing exteral table array processing
CREATE TABLE ext_tab (
sourceno& CHAR(5),
sizeno&&& CHAR(6),
status&&& CHAR(3),
latitude& CHAR(10),
longitude CHAR(11),
testfor&& CHAR(17))
ORGANIZATION EXTERNAL
(TYPE oracle_loader
DEFAULT DIRECTORY ctemp
ACCESS PARAMETERS
(FIELDS TERMINATED BY ','
MISSING FIELD VALUES ARE NULL
(sourceno, sizeno, status, latitude, longitude, testfor))
LOCATION ('sources.txt'))
REJECT LIMIT 10;
CREATE OR REPLACE PROCEDURE array_load IS
CURSOR acur IS
SELECT TRANSLATE(sourceno, 'A''', 'A'),&
TRANSLATE(sizeno, 'A''', 'A'),
TRANSLATE(status, 'A''', 'A'),
TRANSLATE(latitude, 'A''', 'A'),
TRANSLATE(longitude, 'A''', 'A'),
TRANSLATE(testfor, 'A''', 'A')
TYPE&& profarray IS TABLE OF sources_import%ROWTYPE;
& FETCH acur BULK COLLECT INTO l_
& FORALL i IN 1..l_data.COUNT
& INSERT INTO sources_import VALUES l_data(i);
& WHEN OTHERS THEN
&&& RAISE;
END array_
Procedure blending UTL_FILE and array processing
CREATE OR REPLACE PROCEDURE blended IS
&vFileName& VARCHAR2(30) := 'sources.txt';
&vLoc&&&&&& VARCHAR2(20) := 'CTEMP';
&v_InHandle utl_file.file_
&vNewLine&& VARCHAR2(100);
&vLineNo&&& PLS_INTEGER;
&c1&&&&&&&& PLS_INTEGER;
&c2&&&&&&&& PLS_INTEGER;
&c3&&& &&&& PLS_INTEGER;
&c4&&& &&&& PLS_INTEGER;
&c5&&& &&&& PLS_INTEGER;
TYPE profarray IS TABLE OF sources_import%ROWTYPE
INDEX BY BINARY_INTEGER;
& v_InHandle := utl_file.fopen(vLoc, vFileName, 'r');
& vLineNo := 1;
&&&&& utl_file.get_line(v_InHandle, vNewLine);
&&& EXCEPTION
&&&&& WHEN NO_DATA_FOUND THEN
&&&&&&& EXIT;
&&& vNewLine := TRANSLATE(vNewLine, 'A''', 'A');
&&& c1 := INSTR(vNewLine, ',', 1,1);
&&& c2 := INSTR(vNewLine, ',', 1,2);
&&& c3 := INSTR(vNewLine, ',', 1,3);
&&& c4 := INSTR(vNewLine, ',', 1,4);
&&& c5 := INSTR(vNewLine, ',', 1,5);
&&& l_data(vLineNo).sourceno := SUBSTR(vNewLine,1,c1-1);
&&& l_data(vLineNo).sizeno := SUBSTR(vNewLine,c1+1,c2-c1-1);
&&& l_data(vLineNo).status := SUBSTR(vNewLine,c2+1,c3-c2-1);
&&& l_data(vLineNo).latitude := SUBSTR(vNewLine,c3+1,c4-c3-1);
&&& l_data(vLineNo).longitude := SUBSTR(vNewLine,c4+1,c5-c4-1);
&&& l_data(vLineNo).testfor := SUBSTR(vNewLine,c5+1);
&&& vLineNo := vLineNo+1;
& END LOOP;
& utl_file.fclose(v_InHandle);
& FORALL i IN 1..l_data.COUNT
& INSERT INTO sources_import VALUES l_data(i);
& DELETE FROM sources_import WHERE sourceno = 'SOURCENO';
& WHEN OTHERS THEN
&&& RAISE;
Profiling Demo
Profiler Run
set serveroutput on
-- BEGIN RUN 1: BASIC CURSOR LOOP
-- clean out the profiler tables
exec profreset
-- clean out the test tables
TRUNCATE TABLE sources_
-- run the procedure to put it into memory
exec load_sources_
FROM sources_
-- truncate the table before starting again
TRUNCATE TABLE sources_
-- start the profiler
exec dbms_profiler.start_profiler('A')
-- run the procedure
exec load_sources_import
-- stop the profiler
exec dbms_profiler.stop_profiler;
-- get the report
@c: emp\profiler.sql
-- save the report as run1.txt
-- Examine profiler tables
set linesize 121
-- view raw profiler data
SELECT runid, unit_number, line#, total_occur, total_time,
min_time, max_time
FROM plsql_profiler_
SELECT runid, related_run, run_owner, run_date, run_comment,
run_total_time, run_system_info
FROM plsql_profiler_
col unit_type format a20
col unit_name format a25
SELECT runid, unit_number, unit_type, unit_owner, unit_name,
unit_timestamp, total_time
FROM plsql_profiler_
SELECT dump(unit_timestamp)
FROM plsql_profiler_
-- BEGIN RUN 2: COMMA_TO_TABLE
-- clean out the profiler tables
exec profreset
-- clean out the test tables
TRUNCATE TABLE sources_
-- run the procedure to put it into memory
exec load_c2t_
SELECT * FROM sources_
-- clean out the test tables
TRUNCATE TABLE sources_
-- start the profiler
dbms_profiler.start_profiler('B')
-- run the procedure
exec load_c2t_test
-- stop the profiler
dbms_profiler.stop_profiler;
-- get the report
@c: emp\profsum.sql
-- save the report as run2.txt
-- BEGIN RUN 3: ARRAY PROCESSING
-- clean out the profiler tables
exec profreset
-- clean out the test tables
TRUNCATE TABLE sources_
-- run the procedure to put it into memory
exec array_
FROM sources_
-- truncate the table before starting again
TRUNCATE TABLE sources_
-- start the profiler
exec dbms_profiler.start_profiler('C')
-- run the procedure
exec array_load
-- stop the profiler
exec dbms_profiler.stop_profiler;
-- get the report
@c: emp\profsum.sql
-- save the report as run3.txt
-- BEGIN RUN 4: BLENDED PROCESSING
-- clean out the profiler tables
exec profreset
-- clean out the test tables
TRUNCATE TABLE sources_
-- run the procedure to put it into memory
FROM sources_
-- truncate the table before starting again
TRUNCATE TABLE sources_
-- start the profiler
exec dbms_profiler.start_profiler('D')
-- run the procedure
exec blended
-- stop the profiler
exec dbms_profiler.stop_profiler;
-- get the report
@c: emp\profsum.sql
-- save the report as run4.txt
Related Topics
[97 users online] &&
& 2010 psoug.org阻塞与非阻塞:
widows下创建套接字默认都是阻塞型的,阻塞型的好处是处理简单,理解容易,但是处理多个套接字时,就必须创建多个线程,即一个连接socket使用一个线程。而非阻塞模式比如在处理发送和接收数据时,会立即返回,不管是否有有效的数据,这就需要不断测试返回代码,来确定套接字在什么时候可读/可写,也就是确定网络事件何时发生,比如中断默认就是一种事件触发型,比如菜单按钮也是事件触发性,但是比如快递邮寄包裹,他其实使用的是一种任务制(提前规定好的)。windows也提供了众多的非阻塞I/O模型,如select、WSAAsyncSelect、WSAEventSelect、overlapped、completion
port,比如select就可以设置时间,按规定时间去查询事件是否被触发,像WSAAsyncSelect就是事件驱动型的,等,这里主要用在socket端开发服务器程序。
select模型目的:主要是避免在套接字调用上阻塞的应用程序有能力管理多个套接字,即是单一线程模式下只能处理一个套接字的问题,这样可以避免线程膨胀。
select模型函数:
int select(
_In_&&&&&int nfds,
_Inout_&&fd_set *readfds,
_Inout_&&fd_set *writefds,
_Inout_&&fd_set *exceptfds,
_In_&&&&&const struct timeval *timeout
参数说明:
nfds [in]:忽略,仅是为了兼容Berkeley套接字
readfds [in, out]:用来检查可读的套接字组合
writefds [in, out]:用来检查可写的套接字组合
exceptfds [in, out]:用来检查异常的套接字组合
timeout [in]:等待的时间, 如果为NULL,等待的时间为无穷大
返回值:select返回那些即将要被处理的socket总和,假如时间超时,将会返回SOCKET_ERROR,可以使用WSAGetLastError获得出错的原因
Select处理过程:假设以read为例,在这里windows主要是先将套接字s添加到readfds集合中,然后等待select函数返回,在select函数里面会移除没有未决的I/O操作的套接字句柄,即移除未响应的IO套接字句柄,然后看s是否认仍然还是readfs集合中,在就说明s可读了
应用程序:
USHORT usPort = 6000;
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (sListen == INVALID_SOCKET )
TRACE(&create socket error:%d\n&,
WSAGetLastError());
return -1;
addr.sin_family = AF_INET;
addr.sin_port = htons(usPort);
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
if (::bind(sListen, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
/*WSAEFAULT 10014:The system detected an invalid pointer address
in attempting to use a pointer argument in a call.*/
TRACE(&bind socket error: %d\n&,
WSAGetLastError());
return -1;
::listen(sListen, 5);
fd_set fdS
FD_ZERO(&fdSocket);
FD_SET(sListen, &fdSocket);
while (true)
fd_set fdRead = fdS
int nRet = select(0, &fdRead, NULL, NULL, NULL);
if (!nRet || nRet == SOCKET_ERROR
TRACE(&select error: %d\n&,
WSAGetLastError());
return -1;
for (unsigned int i = 0; i & fdSocket.fd_ i++)
if (FD_ISSET(fdSocket.fd_array[i], &fdRead)) //这里选择了fdSocket,是因为下一次循环还要使用fdSocket
if (fdSocket.fd_array[i] == sListen)
if (fdSocket.fd_count & FD_SETSIZE)
sockaddr_in addrR
int nAddrLen = sizeof(addrRemote);
SOCKET sNewClient = ::accept(sListen, (sockaddr*)&addrRemote, &nAddrLen);
if (sNewClient == INVALID_SOCKET )
TRACE(&accept new client socket error: %d\n&,
WSAGetLastError());
FD_SET(sNewClient, &fdSocket);
TRACE(&new client: %s\n&, inet_ntoa(addrRemote.sin_addr));
char szText[256];
int nRecv = ::recv(fdSocket.fd_array[i], szText, sizeof(szText), 0);
if (!nRecv || nRecv == SOCKET_ERROR )
TRACE(&recv data error: %d\n&, WSAGetLastError());
closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i], &fdSocket);
szText[nRecv] = '\0';
TRACE(&recv data: %s&, szText);
}//判断fdsocket里面的socket是否得到处理
closesocket(sListen);
sListen = INVALID_SOCKET;
return 0;这里我使用了CInitSock, 因为在使用socket之前要加载Ws2_32.lib,这里我定义了一个类如下:
#pragma once
#include&winsock2.h&
#include &ws2tcpip.h&
#pragma comment(lib,&Ws2_32.lib&)
class CInitSock
CInitSock(BYTE minVer = 2, BYTE majVer = 2);
~CInitSock(void);
CInitSock::CInitSock(BYTE minVer, BYTE majVer)
WORD wVerReq = MAKEWORD(minVer, majVer);
if (nResult = ::WSAStartup(wVerReq, &wsadata))
TRACE(&WSAStartup Load DLL Failed: %d!\n&, nResult);
CInitSock::~CInitSock(void)
/*In a multithreaded environment, WSACleanup terminates
*Windows Sockets operations for all threads.
::WSACleanup();
}默认构造函数里面有一个默认加载的版本,这里在析构函数里面将之前加载的dll资源进行释放,基础的socket服务器模型通常要进行socket创建,绑定到本地地址和端口,监听客户端的连接,一旦有客户端连接,默认会放入fdSocket中,然后将此函数加入fd_set可读的套接字集合中,select返回后,未响应的socket会被移除,即将要被处理的socket会保留下来,然后从fdSocket判断,到底是哪些socket发生了可读操作:
注意:可读操作包括有未处理的连接请求,数据可读,连接关闭/重启/中断
首先第一个判断的就是未处理的连接请求,如果有就建立新的连接通道,加入fdSocket;如果是数据可读,就读取数据;连接关闭会在下面进行测试
客户端程序:使用的是以前的一个简易客户端程序,如下
WORD wVersionR //请求的版本
WSADATA wsaD
//协商版本号
wVersionRequested = MAKEWORD(1,1);
nErr = WSAStartup(wVersionRequested, &wsaData);
if(nErr != 0)
if( LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1 )
WSACleanup();
//创建socket端口
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrS
addrSrv.sin_addr.S_un.S_addr = inet_addr(&127.0.0.1&);
addrSrv.sin_family
= AF_INET;
addrSrv.sin_port
= htons(6000);
//绑定端口号
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//收发数据
char recvBuf[100], sendBuf[100];
memset(recvBuf, 0, 100);
memset(sendBuf, 0, 100);
sprintf_s(sendBuf,&hello world&);
send(sockClient, sendBuf, strlen(sendBuf)+1, 0);
recv(sockClient, recvBuf, 100, 0);
printf(&%s\n&, recvBuf);
//关闭socket通信
closesocket(sockClient);
WSACleanup();
Sleep(1000);测试结果:
这里需要先运行服务器端,然后再开启客户端程序,服务器端会建立新的连接,并读取客户端发过来的数据然后显示出来,客户端是没有数据的,因为这里服务器端并没有发送数据,如下服务器数据:
再次开启一个客户端的效果如下:
这里并没有进行换行,两行数据在一起了,并不影响测试结果,这里还可以再强制关闭客户端后的结果,如下
这里看到error的代码为10054,我们在winerror.h里面找到如下定义:
// MessageId: WSAECONNRESET
// MessageText:
// An existing connection was forcibly closed by the remote host.
#define WSAECONNRESET
10054L从这里也能看出的确是强制关闭,注意服务器端里面的TRACE要给我printf才可以,TRACE默认是在调试下使用的输出语句
Select不足:其实添加到fd_set套接字数量是有限制的,winsock2.h定义的64,自定义也不超过1024,因为值太大,会对服务器的性能有影响,假设有1000个的话,在调用select之前就必须设置这1000个套接字,select返回之后,还必须检查这1000个套接字,所以开销较大。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:33640次
积分:1066
积分:1066
排名:第17309名
原创:76篇
转载:21篇
(2)(2)(2)(13)(5)(14)(10)(12)(9)(6)(1)(12)(8)(1)

我要回帖

更多关于 windows8和360 的文章

 

随机推荐