导航:首页 > 源码编译 > xsocket源码

xsocket源码

发布时间:2022-01-13 19:32:43

1. VB 如何用:socket 发送数据

1、首先看控件区有无串口控件,表明串口控件并未被启用,选择工程→部件→Micosoft comm Control6.0选项,点击应用,即可添加串口控件。

2. 如何用mina的ProtocolDecoder来解析websocket的消息

MINA,Grizzly[grizzly-nio-framework],xSocket都是基于 java nio的 server framework.

这里的性能缺陷的焦点是指当一条channel上的SelectionKey.OP_READ ready时,1.是由select thread读完数据之后再分发给应用程序的handler,2.还是直接就分发,由handler thread来负责读数据和handle.

mina,xsocket是1. grizzly-nio-framework是2.

尽管读channel buffer中bytes是很快的,但是如果我们放大,当连接channel达到上万数量级,甚至更多,这种延迟响应的效果将会愈加明显.

MINA:

for all selectedKeys

{

read data then fireMessageReceived.

}

xSocket:

for all selectedKeys

{

read data ,append it to readQueue then performOnData.

}

其中mina在fireMessageReceived时没有使用threadpool来分发,所以需要应用程序在handler.messageReceived中再分发.而xsocket的performOnData默认是分发给threadpool[WorkerPool],WorkerPool虽然解决了线程池中的线程不能充到最大的问题[跟tomcat6的做法一样],但是它的调度机制依然缺乏灵活性.

Grizzly:

for all selectedKeys

{

[NIOContext---filterChain.execute--->our filter.execute]<------run In DefaultThreadPool

}

grizzly的DefaultThreadPool几乎重写了java util concurrent threadpool,并使用自己的LinkedTransferQueue,但同样缺乏灵活的池中线程的调度机制.

下面分别是MINA,xSocket,Grizzly的源码分析:

Apache MINA (mina-2.0.0-M6源码为例):

我们使用mina nio tcp最常用的样例如下:

NioSocketAcceptor acceptor = new NioSocketAcceptor(/*NioProcessorPool's size*/);
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();

//chain.addLast("codec", new ProtocolCodecFilter(
//new TextLineCodecFactory()));
......
// Bind
acceptor.setHandler(/*our IoHandler*/);
acceptor.bind(new InetSocketAddress(port));

3. GitHub上面有哪些经典的java框架源码

4. 求聊天系统中客户端通信C/C++源代码!!!

我有, 不是是基于Windows事件模型的 异步的,封装好的。头文件和CPP都有。

5. android_studio手机蓝牙串口通信源代码

初涉android的蓝牙操作,按照固定MAC地址连接获取Device时,程序始终是异常终止,查了好多天代码都没查出原因。今天改了一下API版本,突然就成功连接了。总结之后发现果然是个坑爹之极的错误。

为了这种错误拼命查原因浪费大把时间是非常不值得的,但是问题不解决更是揪心。可惜我网络了那么多,都没有给出确切原因。今天特此mark,希望后来者遇到这个问题的时候能轻松解决。

下面是我的连接过程,中间崩溃原因及解决办法。

1:用AT指令获得蓝牙串口的MAC地址,地址是简写的,按照常理猜测可得标准格式。

2:开一个String adress= "************" //MAC地址, String MY_UUID= "************"//UUID根据通信而定,网上都有。

3:取得本地Adapter用getDefaultAdapter(); 远程的则用getRemoteDevice(adress); 之后便可用UUID开socket进行通信。

如果中途各种在getRemoteDevice处崩溃,大家可以查看一下当前的API版本,如果是2.1或以下版本的话,便能确定是API版本问题,只要换成2.2或者以上就都可以正常运行了~ 这么坑爹的错误的确很为难初学者。 唉·········· 为这种小trick浪费很多时间真是难过。

(另外有个重要地方,别忘了给manifest里面加以下两个蓝牙操作权限哦~)

6. 求一C语言写的tcp程序的源码,程序越简单越好,C++也可以,最好带注释

最简单的那种?我给你写一个=,=
//服务器
#include <sys/stat.h>

#include <fcntl.h>

#include <errno.h>

#include <netdb.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

main()

{
//创建套接字

int serverSocket= socket(AF_INET,SOCK_STREAM,0);

struct sockaddr_in server_addr;

struct sockaddr_in clientAddr;

int addr_len = sizeof(clientAddr);
int client;
char buffer[200];

//创建地址

bzero(&server_addr,sizeof(server_addr));

server_addr.sin_family =AF_INET;

server_addr.sin_port = htons(5555);

server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

//绑定

bind(serverSocket,(struct sockaddr *)&server_addr,sizeof(server_addr));
//帧听

listen(serverSocket,5);
printf("客户端发过来的 :\n");
//接收
client=accept(serverSocket,(sockaddr *)&clientAddr,(socklen_t*)&addr_len);
printf("客户端发过来的 :\n");
while(1)
{
if(recv(client,buffer,sizeof(buffer),0)>0)
printf("客户端发过来的 : %s\n",buffer);
}
return 0;
}

//客户端
#include <sys/stat.h>

#include <fcntl.h>

#include <errno.h>

#include <netdb.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

main()

{

struct sockaddr_in serverAddr;

int clientSocket=socket(AF_INET,SOCK_STREAM,0);

char sendbuf[200];

//创建地址信息

serverAddr.sin_family=AF_INET;

serverAddr.sin_port=htons(5555);

serverAddr.sin_addr.s_addr=inet_addr("127.0.0.1");

//连接服务器

connect(clientSocket,(sockaddr*)&serverAddr,sizeof(serverAddr));

printf("连接目标主机中.....\n连接完成......\n");

//

while(1)

{

printf("请输入发给服务器的数据 : ");

scanf("%s",sendbuf);

//strcmp函数作用,比较两个东东(按ASCII值大小相比较),相同就==0。

if(strcmp(sendbuf,"x")==0)

break;

send(clientSocket,sendbuf,sizeof(sendbuf),0);

}

close(clientSocket);

return 0;

}

7. 分析X-Scan,写出它的使用方法以及配置方法,同时抓包分析其扫描原理。如果有兴趣分析一下其脚本

.命令行:Xscan -h [起始地址]-[终止地址] [扫描选项]
这里如果只对一个ip进行扫描 就不需要填 终止地址了
扫描选项 这里 可以一次填多个 选项
[扫描选项]含义如下:
-p: 扫描标准端口(端口列表可通过\dat\config.ini文件定制);
-b: 获取开放端口的banner信息,需要与-p参数合用;
-c: 扫描CGI漏洞;
-r: 扫描RPC漏洞;
-s: 扫描SQL-SERVER默认帐户;
-f: 尝试FTP默认用户登录(用户名及口令可以通过\dat\config.ini文件定制);
-n: 获取NetBios信息(若远程主机操作系统为Windows9x/NT4.0/2000);
-g: 尝试弱口令用户连接(若远程主机操作系统为Windows NT4.0/2000);
-a: 扫描以上全部内容;
-x [代理服务器:端口]: 通过代理服务器扫描CGI漏洞;
-t: 设置线程数量,默认为20个线程;
-v: 显示详细扫描进度;
-d: 禁止扫描前PING被扫主机。
2.示例:
Xscan -h 222.222.1.1-222.222.10.255 -a
含义:扫描XXX.XXX.1.1-XXX.XXX.10.255网段内主机的所有信息;
Xscan -h xxx.xxx.1.1 -n -g -t 30
含义:获取XXX.XXX.1.1主机的Netbios信息,并检测NT弱口令用户,线程数量为30;
Xscan -h 211.108.1.1 -p -b -c -x 211.108.2.255:80 -v -d

我们来试一下
上面的这些参数都是需要大家来学习掌握的

现在我们进行一个简单的cgi漏洞扫描,这次演练是在控制台模式下进行的:xscan 211.100.8.87 -port
这个命令是让xscan扫描服务器211.100.8.87的开放端口,扫描器不会对65535个端口全部进行扫描(太慢),它只会检测网络上最常用的几百个端口,而且每一个端口对应的网络服务在扫描器中都已经做过定义,从最后返回的结果很容易了解服务器运行了什么网络服务。扫描结果显示如下:
Initialize dynamic library succeed.
Scanning 211.100.8.87 ......
[211.100.8.87]: Scaning port state ...
[211.100.8.87]: Port 21 is listening!!!
[211.100.8.87]: Port 25 is listening!!!
[211.100.8.87]: Port 53 is listening!!!
[211.100.8.87]: Port 79 is listening!!!
[211.100.8.87]: Port 80 is listening!!!
[211.100.8.87]: Port 110 is listening!!!
[211.100.8.87]: Port 3389 is listening!!!
[211.100.8.87]: Port scan completed, found 7.
[211.100.8.87]: All done.
这个结果还会同时在log目录下生成一个html文档,阅读文档可以了解发放的端口对应的服务项目

8. 在远程shell工具里,用"wc"命令,计算一下linux源码包里,总共包含了多少行源码仅限

Linux系统越来越受到电脑用户的欢迎,于是很多人开始学习Linux时,学习linux,你可能会遇到Linux网络操作命令问题,这里将介绍Linux网络操作命令知识,在这里拿出来和大家分享一下。计算机网络的主要优点是能够实现资源和信息的共享,并且用户可以远程访问信息。Linux提供了一组强有力的网络命令来为用户服务,这些工具能够帮助用户登录到远程计算机上、传输文件和执行远程命令等。介绍下列几个常用的有关网络操作命令:ftp传输文件telnet登录到远程计算机上r-使用各种远程命令netstat查看网络的状况nslookup查询域名和IP地址的对应finger查询某个使用者的信息ping查询某个机器是否在工作使用ftp命令进行远程文件传输ftp命令是标准的文件传输协议的用户接口。ftp是在TCP/IP网络上的计算机之间传输文件的简单有效的方法。它允许用户传输ASCII文件和二进制文件。在ftp会话过程中,用户可以通过使用ftp客户程序连接到另一台计算机上。从此,用户可以在目录中上下移动、列出目录内容、把文件从远程机拷贝到本地机上、把文件从本地机传输到远程系统中。需要注意的是,如果用户没有那个文件的存取权限,就不能从远程系统中获得文件或向远程系统传输文件。为了使用ftp来传输文件,用户必须知道远程计算机上的合法用户名和口令。这个用户名/口令的组合用来确认ftp会话,并用来确定用户对要传输的文件可以进行什么样的访问。另外,用户显然需要知道对其进行ftp会话的计算机的名字或IP地址。Ftp命令的功能是在本地机和远程机之间传送文件。该命令的一般格式如下:$ftp主机名/IP其中“主机名/IP”是所要连接的远程机的主机名或IP地址。在命令行中,主机名属于选项,如果指定主机名,ftp将试图与远程机的ftp服务程序进行连接;如果没有指定主机名,ftp将给出提示符,等待用户输入命令:$ftpftp>此时在ftp>提示符后面输入open命令加主机名或IP地址,将试图连接指定的主机。不管使用哪一种方法,如果连接成功,需要在远程机上登录。用户如果在远程机上有帐号,就可以通过ftp使用这一帐号并需要提供口令。在远程机上的用户帐号的读写权限决定该用户在远程机上能下载什么文件和将上载文件放到哪个目录中。如果没有远程机的专用登录帐号,许多ftp站点设有可以使用的特殊帐号。这个帐号的登录名为anonymous(也称为匿名ftp),当使用这一帐号时,要求输入email地址作为口令。如果远程系统提供匿名ftp服务,用户使用这项服务可以登录到特殊的,供公开使用的目录。一般专门提供两个目录:pub目录和incoming目录。pub目录包含该站点供公众使用的所有文件,incoming目录存放上载到该站点的文件。一旦用户使用ftp在远程站点上登录成功,将得到“ftp>”提示符。现在可以自由使用ftp提供的命令,可以用help命令取得可供使用的命令清单,也可以在help命令后面指定具体的命令名称,获得这条命令的说明。最常用的命令有:ls列出远程机的当前目录cd在远程机上改变工作目录lcd在本地机上改变工作目录ascii设置文件传输方式为ASCII模式binary设置文件传输方式为二进制模式close终止当前的ftp会话hash每次传输完数据缓冲区中的数据后就显示一个#号get(mget)从远程机传送指定文件到本地机put(mput)从本地机传送指定文件到远程机open连接远程ftp站点quit断开与远程机的连接并退出ftp?显示本地帮助信息!转到Shell中下面简单将ftp常用命令作一简介。启动ftp会话open命令用于打开一个与远程主机的会话。该命令的一般格式是:open主机名/IP如果在ftp会话期间要与一个以上的站点连接,通常只用不带参数的ftp命令。如果在会话期间只想与一台计算机连接,那么在命令行上指定远程主机名或IP地址作为ftp命令的参数。终止ftp会话close、disconnect、quit和bye命令用于终止与远程机的会话。close和disronnect命令关闭与远程机的连接,但是使用户留在本地计算机的ftp程序中。quit和bye命令都关闭用户与远程机的连接,然后退出用户机上的ftp程序。改变目录“cd[目录]”命令用于在ftp会话期间改变远程机上的目录,lcd命令改变本地目录,使用户能指定查找或放置本地文件的位置。远程目录列表ls命令列出远程目录的内容,就像使用一个交互shell中的ls命令一样。ls命令的一般格式是:ls[目录][本地文件]如果指定了目录作为参数,那么ls就列出该目录的内容。如果给出一个本地文件的名字,那么这个目录列表被放入本地机上您指定的这个文件中。从远程系统获取文件get和mget命令用于从远程机上获取文件。get命令的一般格式为:get文件名您还可以给出本地文件名,这个文件名是这个要获取的文件在您的本地机上创建时的文件名。如果您不给出一个本地文件名,那么就使用远程文件原来的名字。mget命令一次获取多个远程文件。mget命令的一般格式为:mget文件名列表使用用空格分隔的或带通配符的文件名列表来指定要获取的文件,对其中的每个文件都要求用户确认是否传送。向远程系统发送文件put和mput命令用于向远程机发送文件。Put命令的一般格式为:put文件名mput命令一次发送多个本地文件,mput命令的一般格式为:mput文件名列表使用用空格分隔的或带通配符的文件名列表来指定要发送的文件。对其中的每个文件都要求用户确认是否发送。改变文件传输模式默认情况下,ftp按ASCII模式传输文件,用户也可以指定其他模式。ascii和brinary命令的功能是设置传输的模式。用ASCII模式传输文件对纯文本是非常好的,但为避免对二进制文件的破坏,用户可以以二进制模式传输文件。检查传输状态传输大型文件时,可能会发现让ftp提供关于传输情况的反馈信息是非常有用的。hash命令使ftp在每次传输完数据缓冲区中的数据后,就在屏幕上打印一个#字符。本命令在发送和接收文件时都可以使用。ftp中的本地命令当您使用ftp时,字符“!”用于向本地机上的命令shell传送一个命令。如果用户处在ftp会话中,需要shell做某些事,就很有用。例如用户要建立一个目录来保存接收到的文件。如果输入!mkdirnew_dir,那么Linux就在用户当前的本地目录中创建一个名为new_dir的目录。从远程机grunthos下载二进制数据文件的典型对话过程如下:$(grunthos:pc):anonymous33lGuestloginok,sendyourcompletee-mailaddressaspassword.Password:230Guest1oginok,accessrestrictionsapply.RemotesystemtypeisUNIX.ftp>cdpub250CWDcommandsuccessful.ftp>ls200PORTcommandsuccessful./bin/1s..ftp>binary200typesettoI.ftp>hashHashmarkprintingon(1024bytes/hashmark).ftp>.(l4684bytes).#############226Transfercomplete.14684bytesreceivedin0.0473secs(3e+02Kbytes/sec)ftp>quit22lGoodbye.使用telnet命令访问远程计算机用户使用telnet命令进行远程登录。该命令允许用户使用telnet协议在远程计算机之间进行通信,用户可以通过网络在远程计算机上登录,就像登录到本地机上执行命令一样。为了通过telnet登录到远程计算机上,必须知道远程机上的合法用户名和口令。虽然有些系统确实为远程用户提供登录功能,但出于对安全的考虑,要限制来宾的操作权限,因此,这种情况下能使用的功能是很少的。当允许远程用户登录时,系统通常把这些用户放在一个受限制的shell中,以防系统被怀有恶意的或不小心的用户破坏。用户还可以使用telnet从远程站点登录到自己的计算机上,检查电子邮件、编辑文件和运行程序,就像在本地登录一样。但是,用户只能使用基于终端的环境而不是XWndows环境,telnet只为普通终端提供终端仿真,而不支持XWndow等图形环境。telnet命令的一般形式为:telnet主机名/IP其中“主机名/IP”是要连接的远程机的主机名或IP地址。如果这一命令执行成功,将从远程机上得到login:提示符。使用telnet命令登录的过程如下:$telnet主机名/IP启动telnet会话。一旦telnet成功地连接到远程系统上,就显示登录信息并提示用户输人用户名和口令。如果用户名和口令输入正确,就能成功登录并在远程系统上工作。在telnet提示符后面可以输入很多命令,用来控制telnet会话过程,在telnet联机帮助手册中对这些命令有详细的说明。下面是一台Linux计算机上的telnet会话举例:$telnetserver.somewhere.comTrying127.0.0.1…Connectedtoserve.somewhere.com.Escapecharacteris\'?]\'.“TurboLinuxrelease4.0(Colgate)kernel2.0.18onanI486login:bubbapassword:Lastlogin:MonNovl520:50:43forlocalhostLinux2.0.6.(Posix).server:~$server:~$$用户结束了远程会话后,一定要确保使用logout命令退出远程系统。然后telnet报告远程会话被关闭,并返回到用户的本地机的Shell提示符下。r-系列命令除ftp和telnet以外,还可以使用r-系列命令访问远程计算机和在网络上交换文件。使用r-系列命令需要特别注意,因为如果用户不小心,就会造成严重的安全漏洞。用户发出一个r-系列命令后,远程系统检查名为/etc/hosts.equiv的文件,以查看用户的主机是否列在这个文件中。如果它没有找到用户的主机,就检查远程机上同名用户的主目录中名为.rhosts的文件,看是否包括该用户的主机。如果该用户的主机包括在这两个文件中的任何一个之中,该用户执行r-系列命令就不用提供口令。虽然用户每次访问远程机时不用键入口令可能是非常方便的,但是它也可能会带来严重的安全问题。我们建议用户在建立/etc/hosts.equiv和.rhosts文件之前,仔细考虑r-命令隐含的安全问题。rlogin命令rlogin是“remotelogin”(远程登录)的缩写。该命令与telnet命令很相似,允许用户启动远程系统上的交互命令会话。rlogin的一般格式是:rlogin[-8EKLdx][-echar][-krealm][-lusername]host一般最常用的格式是:rloginhost该命令中各选项的含义为:-8此选项始终允许8位输入数据通道。该选项允许发送格式化的ANSI字符和其他的特殊代码。如果不用这个选项,除非远端的终止和启动字符不是或,否则就去掉奇偶校验位。-E停止把任何字符当作转义字符。当和-8选项一起使用时,它提供一个完全的透明连接。-K关闭所有的Kerberos确认。只有与使用Kerberos确认协议的主机连接时才使用这个选项。-L允许rlogin会话在litout模式中运行。要了解信息,请查阅tty联机帮助。-d打开与远程主机进行通信的TCPsockets的socket调试。要了解信息,请查阅setsockopt的联机帮助。-e为rlogin会话设置转义字符,默认的转义字符是“~”,用户可以指定一个文字字符或一个\\nnn形式的八进制数。-k请求rlogin获得在指定区域内的远程主机的Kerberos许可,而不是获得由krb_realmofhost(3)确定的远程主机区域内的远程主机的Kerberos许可。-x为所有通过rlogin会话传送的数据打开DES加密。这会影响响应时间和CPU利用率,但是可以提高安全性。rsh命令rsh是“remoteshell”(远程shell)的缩写。该命令在指定的远程主机上启动一个shell并执行用户在rsh命令行中指定的命令。如果用户没有给出要执行的命令,rsh就用rlogin命令使用户登录到远程机上。rsh命令的一般格式是:rsh[-Kdnx][-krealm][-lusername]host[command]一般常用的格式是:rshhost[command]command可以是从shell提示符下键人的任何Linux命令。rsh命令中各选项的含义如下:-K关闭所有的Kerbero确认。该选项只在与使用Kerbero确认的主机连接时才使用。-d打开与远程主机进行通信的TCPsockets的socket调试。要了解的信息,请查阅setsockopt的联机帮助。-k请求rsh获得在指定区域内的远程主机的Kerberos许可,而不是获得由krb_relmofhost(3)确定的远程主机区域内的远程主机的Kerberos许可。-l缺省情况下,远程用户名与本地用户名相同。本选项允许指定远程用户名,如果指定了远程用户名,则使用Kerberos确认,与在rlogin命令中一样。-n重定向来自特殊设备/dev/null的输入。-x为传送的所有数据打开DES加密。这会影响响应时间和CPU利用率,但是可以提高安全性。Linux把标准输入放入rsh命令中,并把它拷贝到要远程执行的命令的标准输入中。它把远程命令的标准输出拷贝到rsh的标准输出中。它还把远程标准错误拷贝到本地标准错误文件中。任何退出、中止和中断信号都被送到远程命令中。当远程命令终止了,rsh也就终止了。rcp命令rcp代表“remotefile”(远程文件拷贝)。该命令用于在计算机之间拷贝文件。rcp命令有两种格式。第一种格式用于文件到文件的拷贝;第二种格式用于把文件或目录拷贝到另一个目录中。rcp命令的一般格式是:rcp[-px][-krealm]file1file2rcp[-px][-r][-krealm]filedirectory每个文件或目录参数既可以是远程文件名也可以是本地文件名。远程文件名具有如下形式:rname@rhost:path,其中rname是远程用户名,rhost是远程计算机名,path是这个文件的路径。rcp命令的各选项含义如下:-r递归地把源目录中的所有内容拷贝到目的目录中。要使用这个选项,目的必须是一个目录。-p试图保留源文件的修改时间和模式,忽略umask。-k请求rcp获得在指定区域内的远程主机的Kerberos许可,而不是获得由krb_relmofhost(3)确定的远程主机区域内的远程主机的Kerberos许可。-x为传送的所有数据打开DES加密。这会影响响应时间和CPU利用率,但是可以提高安全性。如果在文件名中指定的路径不是完整的路径名,那么这个路径被解释为相对远程机上同名用户的主目录。如果没有给出远程用户名,就使用当前用户名。如果远程机上的路径包含特殊shell字符,需要用反斜线(\\)、双引号(”)或单引号(’)括起来,使所有的shell元字符都能被远程地解释。需要说明的是,rcp不提示输入口令,它通过rsh命令来执行拷贝。-Turbolinux提供稿件。通过本文你就了解Linux网络操作命令,希望对你有所帮助。叹号!进入ftpftp>help!!Escapetotheshell实际叹号!新建shell要再ftp敲exit命令退新建shell即

9. socket 和mina 有区别吗

MINA,Grizzly[grizzly-nio-framework],xSocket都是基于 java nio的 server framework.

这里的性能缺陷的焦点是指当一条channel上的SelectionKey.OP_READ ready时,1.是由select thread读完数据之后再分发给应用程序的handler,2.还是直接就分发,由handler thread来负责读数据和handle.

mina,xsocket是1. grizzly-nio-framework是2.

尽管读channel buffer中bytes是很快的,但是如果我们放大,当连接channel达到上万数量级,甚至更多,这种延迟响应的效果将会愈加明显.

MINA:

for all selectedKeys

{

read data then fireMessageReceived.

}

xSocket:

for all selectedKeys

{

read data ,append it to readQueue then performOnData.

}

其中mina在fireMessageReceived时没有使用threadpool来分发,所以需要应用程序在handler.messageReceived中再分发.而xsocket的performOnData默认是分发给threadpool[WorkerPool],WorkerPool虽然解决了线程池中的线程不能充到最大的问题[跟tomcat6的做法一样],但是它的调度机制依然缺乏灵活性.

Grizzly:

for all selectedKeys

{

[NIOContext---filterChain.execute--->our filter.execute]<------run In DefaultThreadPool

}

grizzly的DefaultThreadPool几乎重写了java util concurrent threadpool,并使用自己的LinkedTransferQueue,但同样缺乏灵活的池中线程的调度机制.下面分别是MINA,xSocket,Grizzly的源码分析:

Apache MINA (mina-2.0.0-M6源码为例):

我们使用mina nio tcp最常用的样例如下:

NioSocketAcceptor acceptor = new NioSocketAcceptor(/*NioProcessorPool's size*/);
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();


//chain.addLast("codec", new ProtocolCodecFilter(
//new TextLineCodecFactory()));
......
// Bind
acceptor.setHandler(/*our IoHandler*/);
acceptor.bind(new InetSocketAddress(port));

------------------------------------------------------------------------------------

首先从NioSocketAcceptor(extends AbstractPollingIoAcceptor)开始,

bind(SocketAddress)--->bindInternal--->startupAcceptor:启动AbstractPollingIoAcceptor.Acceptor.run使用executor[Executor]的线程,注册[interestOps:SelectionKey.OP_ACCEPT],然后wakeup selector.

一旦有连接进来就构建NioSocketSession--对应--channal,然后session.getProcessor().add(session)将当前的channal加入到NioProcessor的selector中去[interestOps:SelectionKey.OP_READ],这样每个连接中有请求过来就由相应的NioProcessor来处理.

这里有几点要说明的是:
1.一个NioSocketAcceptor对应了多个NioProcessor,比如NioSocketAcceptor就使用了SimpleIoProcessorPool DEFAULT_SIZE = Runtime.getRuntime().availableProcessors() + 1.当然这个size在new NioSocketAcceptor的时候可以设定.
2.一个NioSocketAcceptor对应一个java nio selector[OP_ACCEPT],一个NioProcessor也对应一个java nio selector[OP_READ].
3.一个NioSocketAcceptor对应一个内部的AbstractPollingIoAcceptor.Acceptor---thread.
4.一个NioProcessor也对应一个内部的AbstractPollingIoProcessor.Processor---thread.
5.在new NioSocketAcceptor的时候如果你不提供Executor(线程池)的话,那么默认使用Executors.newCachedThreadPool().
这个Executor将被NioSocketAcceptor和NioProcessor公用,也就是说上面的Acceptor---thread(一条)和Processor---thread(多条)都是源于这个Executor.

当一个连接java nio channal--NioSession被加到ProcessorPool[i]--NioProcessor中去后就转入了AbstractPollingIoProcessor.Processor.run,
AbstractPollingIoProcessor.Processor.run方法是运行在上面的Executor中的一条线程中的,当前的NioProcessor将处理注册在它的selector上的所有连接的请求[interestOps:SelectionKey.OP_READ].

AbstractPollingIoProcessor.Processor.run的主要执行流程:

for (;;) {
......
int selected = selector(final SELECT_TIMEOUT = 1000L);
.......
if (selected > 0) {
process();
}
......
}

process()-->for all session-channal:OP_READ -->read(session):这个read方法是AbstractPollingIoProcessor.private void read(T session)方法.
read(session)的主要执行流程是read channal-data to buf,if readBytes>0 then IoFilterChain.fireMessageReceived(buf)/*我们的IoHandler.messageReceived将在其中被调用*/;

到此mina Nio 处理请求的流程已经明了.

mina处理请求的线程模型也出来了,性能问题也来了,那就是在AbstractPollingIoProcessor.Processor.run-->process-->read(per session)中,在process的时候mina是for all selected-channals 逐次read data再fireMessageReceived到我们的IoHandler.messageReceived中,而不是并发处理,这样一来很明显后来的请求将被延迟处理.

我们假设:如果NioProcessorPool's size=2 现在有200个客户端同时连接过来,假设每个NioProcessor都注册了100个连接,对于每个NioProcessor将依次顺序处理这100个请求,那么这其中的第100个请求要得到处理,那它只有等到前面的99个被处理完了.
有人提出了改进方案,那就是在我们自己的IoHandler.messageReceived中利用线程池再进行分发dispatching,这个当然是个好主意.
但是请求还是被延迟处理了,因为还有read data所消耗的时间,这样第100个请求它的数据要被读,就要等前面的99个都被读完才行,即便是增加ProcessorPool的尺寸也不能解决这个问题.

此外mina的陷阱(这个词较时髦)也出来了,就是在read(session)中,在说这个陷阱之前先说明一下,我们的client端向server端发送一个消息体的时候不一定是完整的只发送一次,可能分多次发送,特别是在client端忙或要发送的消息体的长度较长的时候.而mina在这种情况下就会call我们的IoHandler.messageReceived多次,结果就是消息体被分割了若干份,等于我们在IoHandler.messageReceived中每次处理的数据都是不完整的,这会导致数据丢失,无效.
下面是read(session)的源码:
private void read(T session) {
IoSessionConfig config = session.getConfig();
IoBuffer buf = IoBuffer.allocate(config.getReadBufferSize());

final boolean hasFragmentation =
session.getTransportMetadata().hasFragmentation();

try {
int readBytes = 0;
int ret;

try {
if (hasFragmentation/*hasFragmentation一定为ture,也许mina的开发人员也意识到了传输数据的碎片问题,但是靠下面的处理是远远不够的,因为client一旦间隔发送,ret就可能为0,退出while,不完整的readBytes将被fire*/) {
while ((ret = read(session, buf)) > 0) {
readBytes += ret;
if (!buf.hasRemaining()) {
break;
}
}
} else {
ret = read(session, buf);
if (ret > 0) {
readBytes = ret;
}
}
} finally {
buf.flip();
}

if (readBytes > 0) {
IoFilterChain filterChain = session.getFilterChain();
filterChain.fireMessageReceived(buf);
buf = null;

if (hasFragmentation) {
if (readBytes << 1 < config.getReadBufferSize()) {
session.decreaseReadBufferSize();
} else if (readBytes == config.getReadBufferSize()) {
session.increaseReadBufferSize();
}
}
}
if (ret < 0) {
scheleRemove(session);
}
} catch (Throwable e) {
if (e instanceof IOException) {
scheleRemove(session);
}
IoFilterChain filterChain = session.getFilterChain();
filterChain.fireExceptionCaught(e);
}
}
这个陷阱大家可以测试一下,看会不会一个完整的消息被多次发送,你的IoHandler.messageReceived有没有被多次调用.
要保持我们应用程序消息体的完整性也很简单只需创建一个断点breakpoint,然后set it to the current IoSession,一旦消息体数据完整就dispatching it and remove it from the current session.

--------------------------------------------------------------------------------------------------

下面以xSocket v2_8_8源码为例:

tcp usage e.g:

IServer srv = new Server(8090, new EchoHandler());
srv.start() or run();

-----------------------------------------------------------------------

class EchoHandler implements IDataHandler {
public boolean onData(INonBlockingConnection nbc)
throws IOException,
BufferUnderflowException,
MaxReadSizeExceededException {
String data = nbc.readStringByDelimiter("/r/n");
nbc.write(data + "/r/n");
return true;
}
}

------------------------------------------------------------------------

说明1.Server:Acceptor:IDataHandler ------1:1:1

Server.run-->IoAcceptor.accept()在port上阻塞,一旦有channel就从IoSocketDispatcherPool中获取一个IoSocketDispatcher,同时构建一个IoSocketHandler和NonBlockingConnection,调用

Server.LifeCycleHandler.onConnectionAccepted(ioHandler) initialize the IoSocketHandler.注意:IoSocketDispatcherPool.size默认为2,也就是说只有2条do select的线程和相应的2个IoSocketDispatcher.这个和MINA的NioProcessor数是一样的.

说明2.IoSocketDispatcher[java nio Selector]:IoSocketHandler:NonBlockingConnection------1:1:1

在IoSocketDispatcher[对应一个Selector].run中--->IoSocketDispatcher.handleReadWriteKeys:

for all selectedKeys

{

IoSocketHandler.onReadableEvent/onWriteableEvent.

}

IoSocketHandler.onReadableEvent的处理过程如下:

1.readSocket();

2.NonBlockingConnection.IoHandlerCallback.onData

NonBlockingConnection.onData--->appendDataToReadBuffer: readQueue append data

3.NonBlockingConnection.IoHandlerCallback.onPostData

NonBlockingConnection.onPostData--->HandlerAdapter.onData[our dataHandler] performOnData in WorkerPool[threadpool].因为是把channel中的数据读到readQueue中,应用程序的dataHandler.onData会被多次调用直到readQueue中的数据读完为止.所以依然存在类似mina的陷阱.解决的方法依然类似,因为这里有NonBlockingConnection.

----------------------------------------------------------------------------------------------

再下面以grizzly-nio-framework v1.9.18源码为例:

tcp usage e.g:

Controller sel = new Controller();
sel.(new (){
public ProtocolChain poll() {
ProtocolChain protocolChain = protocolChains.poll();
if (protocolChain == null){
protocolChain = new DefaultProtocolChain();
//protocolChain.addFilter(our app's filter/*应用程序的处理从filter开始,类似mina.ioHandler,xSocket.dataHandler*/);
//protocolChain.addFilter(new ReadFilter());
}
return protocolChain;
}
});

//如果你不增加自己的SelectorHandler,Controller就默认使用TCPSelectorHandler port:18888
sel.addSelectorHandler(our app's selectorHandler on special port);
sel.start();

------------------------------------------------------------------------------------------------------------

说明1.Controller:ProtocolChain:Filter------1:1:n,

Controller:SelectorHandler------1:n,SelectorHandler[对应一个Selector]:SelectorHandlerRunner------1:1,

Controller. start()--->for per SelectorHandler start SelectorHandlerRunner to run.

SelectorHandlerRunner.run()--->selectorHandler.select() then handleSelectedKeys:

for all selectedKeys

{

NIOContext.execute:dispatching to threadpool for ProtocolChain.execute--->our filter.execute.

}你会发现这里没有read data from channel的动作,因为这将由你的filter来完成.所以自然没有mina,xsocket它们的陷阱问题,分发提前了.但是你要注意SelectorHandler:Selector:SelectorHandlerRunner:Thread[SelectorHandlerRunner.run]都是1:1:1:1,也就是说只有一条线程在doSelect then handleSelectedKeys.
相比之下虽然grizzly在并发性能上更优,但是在易用性方面却不如mina,xsocket,比如类似mina,xsocket中表示当前连接或会话的IoSession,INonBlockingConnection对象在grizzly中由NIOContext来负责,但是NIOContext并没有提供session/connection lifecycle event,以及常规的read/write操作,这些都需要你自己去扩展SelectorHandler和ProtocolFilter,从另一个方面也可以说明grizzly的可扩展性,灵活性更胜一筹.
转载

10. php100 socket类源码

email.class.php <?php class smtp { /* Public Variables */ var $smtp_port; var $time_out; var $host_name; var $log_file; var $relay_host; var $debug; var $auth; var $user; var $pass; /* Private Variables */ var $sock; /* Constractor */ function smtp($relay_host = "", $smtp_port = 25,$auth = false,$user,$pass) { $this->debug = FALSE; $this->smtp_port = $smtp_port; $this->relay_host = $relay_host; $this->time_out = 30; //is used in fsockopen() # $this->auth = $auth;//auth $this->user = $user; $this->pass = $pass; # $this->host_name = "localhost"; //is used in HELO command $this->log_file =""; $this->sock = FALSE; } /* Main Function */ function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "") { $mail_from = $this->get_address($this->strip_comment($from)); $body = ereg_replace("(^|(\r\n))(\\.)", "\\1.\\3", $body); $header .= "MIME-Version:1.0\r\n"; if($mailtype=="HTML"){ $header .= "Content-Type:text/html\r\n"; } $header .= "To: ".$to."\r\n"; if ($cc != "") { $header .= "Cc: ".$cc."\r\n"; } $header .= "From: $from<".$from.">\r\n"; $header .= "Subject: ".$subject."\r\n"; $header .= $additional_headers; $header .= "Date: ".date("r")."\r\n"; $header .= "X-Mailer:By Redhat (PHP/".phpversion().")\r\n"; list($msec, $sec) = explode(" ", microtime()); $header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from.">\r\n"; $TO = explode(",", $this->strip_comment($to)); if ($cc != "") { $TO = array_merge($TO, explode(",", $this->strip_comment($cc))); } if ($bcc != "") { $TO = array_merge($TO, explode(",", $this->strip_comment($bcc))); } $sent = TRUE; foreach ($TO as $rcpt_to) { $rcpt_to = $this->get_address($rcpt_to); if (!$this->smtp_sockopen($rcpt_to)) { $this->log_write("Error: Cannot send email to ".$rcpt_to."\n"); $sent = FALSE; continue; } if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body)) { $this->log_write("E-mail has been sent to <".$rcpt_to.">\n"); } else { $this->log_write("Error: Cannot send email to <".$rcpt_to.">\n"); $sent = FALSE; } fclose($this->sock); $this->log_write("Disconnected from remote host\n"); } echo "<br>"; echo $header; return $sent; } /* Private Functions */ function smtp_send($helo, $from, $to, $header, $body = "") { if (!$this->smtp_putcmd("HELO", $helo)) { return $this->smtp_error("sending HELO command"); } #auth if($this->auth){ if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user))) { return $this->smtp_error("sending HELO command"); } if (!$this->smtp_putcmd("", base64_encode($this->pass))) { return $this->smtp_error("sending HELO command"); } } # if (!$this->smtp_putcmd("MAIL", "FROM:<".$from.">")) { return $this->smtp_error("sending MAIL FROM command"); } if (!$this->smtp_putcmd("RCPT", "TO:<".$to.">")) { return $this->smtp_error("sending RCPT TO command"); } if (!$this->smtp_putcmd("DATA")) { return $this->smtp_error("sending DATA command"); } if (!$this->smtp_message($header, $body)) { return $this->smtp_error("sending message"); } if (!$this->smtp_eom()) { return $this->smtp_error("sending <CR><LF>.<CR><LF> [EOM]"); } if (!$this->smtp_putcmd("QUIT")) { return $this->smtp_error("sending QUIT command"); } return TRUE; } function smtp_sockopen($address) { if ($this->relay_host == "") { return $this->smtp_sockopen_mx($address); } else { return $this->smtp_sockopen_relay(); } } function smtp_sockopen_relay() { $this->log_write("Trying to ".$this->relay_host.":".$this->smtp_port."\n"); $this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out); if (!($this->sock && $this->smtp_ok())) { $this->log_write("Error: Cannot connenct to relay host ".$this->relay_host."\n"); $this->log_write("Error: ".$errstr." (".$errno.")\n"); return FALSE; } $this->log_write("Connected to relay host ".$this->relay_host."\n"); return TRUE;; } function smtp_sockopen_mx($address) { $domain = ereg_replace("^.+@([^@]+)$", "\\1", $address); if (!@getmxrr($domain, $MXHOSTS)) { $this->log_write("Error: Cannot resolve MX \"".$domain."\"\n"); return FALSE; } foreach ($MXHOSTS as $host) { $this->log_write("Trying to ".$host.":".$this->smtp_port."\n"); $this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out); if (!($this->sock && $this->smtp_ok())) { $this->log_write("Warning: Cannot connect to mx host ".$host."\n"); $this->log_write("Error: ".$errstr." (".$errno.")\n"); continue; } $this->log_write("Connected to mx host ".$host."\n"); return TRUE; } $this->log_write("Error: Cannot connect to any mx hosts (".implode(", ", $MXHOSTS).")\n"); return FALSE; } function smtp_message($header, $body) { fputs($this->sock, $header."\r\n".$body); $this->smtp_debug("> ".str_replace("\r\n", "\n"."> ", $header."\n> ".$body."\n> ")); return TRUE; } function smtp_eom() { fputs($this->sock, "\r\n.\r\n"); $this->smtp_debug(". [EOM]\n"); return $this->smtp_ok(); } function smtp_ok() { $response = str_replace("\r\n", "", fgets($this->sock, 512)); $this->smtp_debug($response."\n"); if (!ereg("^[23]", $response)) { fputs($this->sock, "QUIT\r\n"); fgets($this->sock, 512); $this->log_write("Error: Remote host returned \"".$response."\"\n"); return FALSE; } return TRUE; } function smtp_putcmd($cmd, $arg = "") { if ($arg != "") { if($cmd=="") $cmd = $arg; else $cmd = $cmd." ".$arg; } fputs($this->sock, $cmd."\r\n"); $this->smtp_debug("> ".$cmd."\n"); return $this->smtp_ok(); } function smtp_error($string) { $this->log_write("Error: Error occurred while ".$string.".\n"); return FALSE; } function log_write($message) { $this->smtp_debug($message); if ($this->log_file == "") { return TRUE; } $message = date("M d H:i:s ").get_current_user()."[".getmypid()."]: ".$message; if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a"))) { $this->smtp_debug("Warning: Cannot open log file \"".$this->log_file."\"\n"); return FALSE; } flock($fp, LOCK_EX); fputs($fp, $message); fclose($fp); return TRUE; } function strip_comment($address) { $comment = "\\([^()]*\\)"; while (ereg($comment, $address)) { $address = ereg_replace($comment, "", $address); } return $address; } function get_address($address) { $address = ereg_replace("([ \t\r\n])+", "", $address); $address = ereg_replace("^.*<(.+)>.*$", "\\1", $address); return $address; } function smtp_debug($message) { if ($this->debug) { echo $message."<br>"; } } function get_attach_type($image_tag) { // $filedata = array(); $img_file_con=fopen($image_tag,"r"); unset($image_data); while ($tem_buffer=AddSlashes(fread($img_file_con,filesize($image_tag)))) $image_data.=$tem_buffer; fclose($img_file_con); $filedata['context'] = $image_data; $filedata['filename']= basename($image_tag); $extension=substr($image_tag,strrpos($image_tag,"."),strlen($image_tag)-strrpos($image_tag,".")); switch($extension){ case ".gif": $filedata['type'] = "image/gif"; break; case ".gz": $filedata['type'] = "application/x-gzip"; break; case ".htm": $filedata['type'] = "text/html"; break; case ".html": $filedata['type'] = "text/html"; break; case ".jpg": $filedata['type'] = "image/jpeg"; break; case ".tar": $filedata['type'] = "application/x-tar"; break; case ".txt": $filedata['type'] = "text/plain"; break; case ".zip": $filedata['type'] = "application/zip"; break; default: $filedata['type'] = "application/octet-stream"; break; } return $filedata; } } ?> ----------------------------------------- sendmail.php <?php require_once ('email.class.php'); //########################################## $smtpserver = "smtp.163.com";//SMTP服务器 $smtpserverport =25;//SMTP服务器端口 $smtpusermail = "";//SMTP服务器的用户邮箱 $smtpemailto = "";//发送给谁 $smtpuser = "";//SMTP服务器的用户帐号 $smtppass = "";//SMTP服务器的用户密码 $mailsubject = "PHP100测试邮件系统";//邮件主题 $mailbody = "<h1> 这是一个测试程序 PHP100.com </h1>";//邮件内容 $mailtype = "HTML";//邮件格式(HTML/TXT),TXT为文本邮件 ########################################## $smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);//这里面的一个true是表示使用身份验证,否则不使用身份验证. $smtp->debug = FALSE;//是否显示发送的调试信息 $smtp->sendmail($smtpemailto, $smtpusermail, $mailsubject, $mailbody, $mailtype); ?>

阅读全文

与xsocket源码相关的资料

热点内容
云服务器30m 浏览:25
古装程序员电视剧 浏览:180
爱因斯坦传pdf 浏览:495
块存储和云服务器 浏览:352
吃东西的解压生 浏览:916
如何把网页上传到web服务器 浏览:243
外国超级解压实验 浏览:63
pdf阅读器官方免费下载 浏览:46
禁止的命令 浏览:963
java设置button的大小设置 浏览:451
ios程序员提升方向 浏览:528
源码封库时引用的库怎么处理 浏览:524
鲨鱼源码最新版 浏览:677
节点是服务器地址吗 浏览:630
服务器为什么不能搬走 浏览:315
三年无工作经验空窗期的程序员 浏览:561
来球网app怎么样 浏览:302
51单片机哈佛 浏览:571
无法下载华为移动服务器地址 浏览:679
phplinux重启命令 浏览:110