c#怎样用使用TcpIp,Socket建立网络连接。就是启动服务器 进行监听
public delegate void ServerEventHandler(object sender, ServerEventArgs args);
public class Server
{
public SystemNetSocketsTcpListener listener;
public event ServerEventHandler serverHandler;
public void StartServer()
{
SystemTextEncoding enc = SystemTextEncodingUTF8;
string host = SystemNetDnsGetHostName();
int port = 2001;
SystemNetIPAddress ipAdd = null;
foreach (SystemNetIPAddress ipAddress in
SystemNetDnsGetHostEntry(SystemNetDnsGetHostName())AddressList)
{
if (!ipAddressIsIPv6LinkLocal)
ipAdd = ipAddress;
}
if (null == ipAdd) return;
listener = new SystemNetSocketsTcpListener(ipAdd, port);
try
{
listenerStart();
}
catch
{
return;
}
while (true)
{
SystemNetSocketsTcpClient tcp = listenerAcceptTcpClient();
SystemNetSocketsNetworkStream ns = tcpGetStream();
SystemIOMemoryStream ms = new SystemIOMemoryStream();
byte[] resBytes = new byte[256];
int resSize;
do
{
resSize = nsRead(resBytes, 0, resBytesLength);
if (resSize == 0)
{
return;
}
msWrite(resBytes, 0, resSize);
} while (nsDataAvailable);
string resMsg = encGetString(msToArray());
serverHandler(this, new ServerEventArgs(thisGetRemoteIP(tcp), resMsg));
msClose();
string sendMsg = resMsgLengthToString() + "characters";
byte[] sendBytes = encGetBytes(sendMsg);
nsWrite(sendBytes, 0, sendBytesLength);
tcpClose();
}
}
public void StopServer()
{
listenerStop();
}
#region Get Remote IP and Port Number。
public string GetRemoteIP(SystemNetSocketsTcpClient cln)
{
string ip = clnClientRemoteEndPointToString()Split(':')[0];
return ip;
}
public int GetRemotePort(SystemNetSocketsTcpClient cln)
{
string temp = clnClientRemoteEndPointToString()Split(':')[1];
int port = SystemConvertToInt32(temp);
return port;
}
#endregion
}
最简单的方法:
下一个代码运行起来慢慢改。。
Windows 2000/XP/2003系统中的远程终端服务是一项功能非常强大的服务,同时也成了入侵者长驻主机的通道,入侵者可以利用一些手段得到管理员账号和密码并入侵主机。下面,我们来看看如何通过修改默认端口,防范黑客入侵。
众所周知,远程终端服务基于端口3389。入侵者一般先扫描主机开放端口,一旦发现其开放了3389端口,就会进行下一步的入侵,所以我们只需要修改该务默认端口就可以避开大多数入侵者的耳目。
步骤:打开“开始→运行”,输入“regedit”,打开注册表,进入以下路径:[HKEY_LOCAL_MACHINE/SYSTEM/
CurrentControlSet/Control/Terminal Server/
Wds/rdpwd/Tds/tcp],看见PortNamber值了吗双击打开后选择十进制-->数值数据:其默认值是3389,修改成所希望的端口即可,例如9090。
再打开[HKEY_LOCAL_MACHINE/
SYSTEM/CurrentContro1Set/Control/Tenninal Server/WinStations/RDP/Tcp],将PortNumber的值(默认是3389)修改成端口9090。
设置完成修改后,要想生效还要重新启动服务器,注:在重启服务器前,请务必确定系统防火墙已经把9090端口进去了,以免系统开了防火墙。重启服务器后。服务器远程不了了。重启以后远程登录的时候使用端口9090就可以了。如在远程桌面输入图
在收到消息的函数里面,会有一个参数,如果是用Windows API做的话,就有一个sockaddr_in的结构体,里面包含了对方的IP和端口,记得端口是高低字节错位的,把高8位和低8位调换一下就好了。
有了对方的IP和端口,直接再向这个IP和端口发消息就好了。
Oracle监听器是Oracle服务器软件的一个组件,它负责管理Oracle数据库和客户端之间的通讯,它在一个特定的网卡端口(默认是TCP 15
Oracle监听器简介
Oracle监听器是Oracle服务器软件的一个组件,它负责管理Oracle数据库和客户端之间的通讯,它在一个特定的网卡端口(默认是TCP 1521端口)上监听连接请求,并将连接转发给数据库,由两个二进制文件组成:tnslsnr和lsnrctl。其中tsnlsnr就是监听器本身,它运行在数据库服务器端,lsnrctl是监听器控制程序,用于在服务器上或远程管理监听器。与监听器相关的还有两个配置文件:sqlnetora和listenerora。tnslsnr启动时就会读取这两个配置文件中的信息,如端口号,数据库服务名。
Oracle监听器在默认安装和配置情况下,有许多著名的漏洞和缺陷,黑客利用这些缺陷可以制造拒绝服务攻击,偷窃数据库连接密码,进一步窃取机密数据。最大的风险来自监听器的配置,Oracle官方提供了一些推荐的配置,往往能够达到保护监听器的目的。本文就是想仔细列出现有的已知保护Oracle监听器的方法,这些方法对于黑客而言都很熟悉,所以作为DBA也必须要清楚才行。
为什么要保护监听器?
DBA对于为什么要保护监听器往往不太关心,他们认为黑客不太可能通过控制监听器进而控制整个数据库,在Oracle 10g之前的所有版本,Oracle监听器允许任何一个人利用lsnrctl从远程发起对监听器的管理,但幸运的是,从Oracle 101开始严格限制在远程对监听器的管理了。下面列出一些对Oracle 8/9i默认安装配置时可能有效的攻击手段,即使是打上最新的安全补丁,而没有进行安全配置加固,这些攻击手段也仍然有效:
注意:本文假设监听器使用的是TCP/IP,并且使用的是本地命名管理(即tnsnamesora),本文所描述的Oracle版本在8i/9i/10g上做过测试,但相信对其他低版本或更高的版本也有一定的参考价值。
怎么保护监听器?
既然监听器有这么多可供黑客利用的地方,那有没有什么方法来保护它,办法是有的,而且还很多,总结起来,大概有下面11种方法来保护Oracle监听器:
1、 设备监听器密码
通过设置监听器密码可以阻止大部分的菜鸟黑客的进攻,设置密码有两种方法,一种是通过lsnrctl命令来设置,另一种是直接修改listenerora文件,第一种方法设置的密码是经过加密后存储在listenerora中,而第二种方法是以明文的形式放在listenerora中的,所以推荐使用第一种方式。具体命令如下:
LSNRCTL> set current_listener
LSNRCTL> change_password
old password:
New password:
Reenter new password:
LSNRCTL> set password Password:
LSNRCTL> save_config
设置好密码后,打开listenerora,看是否有一条PASSWORDS_的记录,类似于PASSWORDS_LISTENER = F4BAA4A006C26134。为监听器设置了密码后,,必须到客户端重新配置连接。
2、 开启监听器日志
开启监听器日志功能是为了捕获监听器命令和防止密码被暴力破解。开启监听器日志功能的命令为:
LSNRCTL> set current_listener
LSNRCTL> set password Password:
LSNRCTL> set log_directory /network/admin
LSNRCTL> set log_file log
LSNRCTL> set log_status on
LSNRCTL> save_config
通过运行上面的命令,监听器将会在/network/admin目录下创建一个log日志文件,以后可以打开该文件查看一些常见的ORA-错误信息。
3、 在listenerora中设置ADMIN_RESTRICTIONS
在listenerora文件中设置了ADMIN_RESTRICTIONS参数后,当监听器在运行时,不允许执行任何管理任何,届时,set命令将不可用,不论是在服务器本地还是从远程执行都不行,这时如果要修改监听器设置就只有手工修改listenerora文件了,通过手工修改listenerora,要使修改生效,只能使用lsnrctl reload命令或lsnrctl stop/start命令重新载入一次监听器配置信息。在listenerora文件中手动加入下面这样一行:
ADMIN_RESTRICTIONS_ = ON
4、 打上最新的监听器补丁
这一点就与操作系统类似,数据库也有bug,也有漏洞,黑客会在漏洞发现第一时间扫描未打补丁的服务器,所以作为一个称职的DBA要随时关注Oracle的CPU(呵呵,不是处理器,是关键补丁升级的意思),这里要说明的是Oracle的补丁是自动累加的,就像windows xp sp2的内容包括了sp1的所有内容一样,所以只需要按照最新的补丁集就可以了,还有一点要注意的是在生产系统上应用任何补丁前都需要先在测试环境进行测试,保证升级后不影响正常业务才进行升级。最后要说明的是,只有购买了Oracle的正式许可才可以登陆下载补丁,否则就只有从第三方地址下载,其完整性就不能保证了。
5、 利用防火墙阻止SQLNET
除非的确需要,否则不应该让SQLNET通讯通过防火墙,在设计防火墙规则时,应设计为只允许经过认证的Web服务器和应用程序通过防火墙进行SQLNET通信。而且放在防火墙DMZ区域的应用服务器使用SQLNET通信时,应只允许它与特定的数据库服务器进行通信。
通常很少有应用会从Internet直接访问数据库,因为这种方式的延迟非常明显,通用的做法是配置应用服务器与数据库通信,Internet客户端通过浏览器访问应用服务器即可,这时配置防火墙时也只需设置应用服务器和数据库服务器之间的通信规则即可。
6、 保护$TNS_ADMIN目录
$TNS_ADMIN目录即我们通常看到的ORACLE_HOME/network/admin目录,它下面包含有listenerora,tnsnamesora,sqlnetora,protocolora等重要配置文件,前面已经提到,监听器的密码就是保存在listenerora中的,如果不保护好,可能造成密码泄露,或整个文件被修改,这个目录下的listenerora,sqlnetora,protocolora文件应该只开放给Oracle主账户(通常是oracle或Administrator),而其他账户不能有任何权限,tnsnamesora文件在Linux或Unix系统上权限可以设置为0644,在windows上可以设置其他用户为浏览,读取权限。
7、 保护TNSLSNR和LSNRCTL
在Linux或Unix服务器上,应该将这两个文件的权限设为0751,如果想更严格一点,可以设为0700,这样就只有安装oracle时指定的宿主用户可以执行它们了,这两个文件位于ORACLE_HOME/bin目录下。保护这两个文件的目的是为了防止黑客直接破坏它们,如果tnslsnr被破坏,监听器肯定不能启动,如果lsnrctl被破坏,可能植入恶意代码,在运行lsnrctl时就会执行其它黑客行为。
8、 移除不用的服务
默认安装时,会安装一个PL/SQL外部程序(ExtProc)条目在listenerora中,它的名字通常是ExtProc或PLSExtProc,但一般不会使用它,可以直接从listenerora中将这项移除,因为对ExtProc已经有多种攻击手段了。有时可能会在多个实例之间拷贝listenerora,请检查拷贝来的文件中是否含有不需要的服务,确保只留下的确需要的服务项目,减少监听器受攻击的面。
9、 改变默认的TNS端口号
改变监听器监听的端口号与修改ftp服务器默认的21端口,web服务器的80端口类似,因为Oracle默认的监听端口是1521(Oracle还正式注册了两个新的端口号2483和2484,说不定哪个新版本发布后,可能默认的端口号就会是这两个了,其中2484用于SSL类型的连接),几乎所有的扫描器都可以直接扫描这个端口是否打开,如果设置为一个不常用的端口号,可能会给人一种假象,而且即使扫描到端口打开,也还要猜测该端口运行是究竟是什么服务,攻击难度就加大了。在修改端口的时候也不要设在1521-1550和1600-1699范围内,虽然通过修改默认端口并不算什么高级防护技术,但至少可以防止自动攻击,以及在端口1521上的简单扫描。
可直接编辑listenerora中端口号,也可以通过netca程序进行修改,当然在客户端也要做对应的修改才行。同时要设置初始化参数LOCAL_LISTENER,这样在监听端口发生变化后,数据库才会自动进行监听器重新注册。
10、 设置节点验证
根据应用程序和网络配置情况,采用节点验证对于保护监听器是一种强有力的方法,大部分Web应用程序都只需要从应用服务器访问监听器,以及一台管理客户端,对于Oracle 8/8i,在$ORACLE_HOME/network/admin/protocolora文件中添加节点检查语句,对于Oracle 9i/10g,在$ORACLE_HOME/network/admin/sqlnetora文件中添加节点检查语句,语句的格式都一样,如:
tcpvalidnode_checking = yes
tcpinvited_nodes = ( xxxx | name, xxxx | name)
tcpexcluded_nodes=( xxxx | name, xxxx | name)
注意:这里要么使用invited_nodes语句,要么使用excluded_nodes,不能同时都使用,也不能使用通配符,子网等,只能使用明确的ip地址或主机名。这里的xxxx指的就是如1921681100这样的ip地址,name就是主机名,如果有多个ip地址或主机名,使用逗号进行分隔。
设置了节点验证后,监听器需要重新启动才会生效。使用这种方法进行节点验证会消耗一定的系统资源和网络带宽,如果要验证的地址过多,靠手工添加也很麻烦,这时可以使用Oracle Connection Manager,如果是有许多客户端通过SQLNET访问数据库,使用这种节点验证的方法也不可行,那会相当的慢。
11、 监视日志
在前面的方法中开启了监听器日志功能,在产生了日志信息后,要对其进行分析,常见的可在日志文件中查找是否有TNS-01169,TNS-01189,TNS-01190或TNS-12508错误,如果有这些错误,至少可以说明要么有人攻击,要么有异常活动,进一步可以使用shell基本或一些简单的管理工具将这些有用的日志信息定期发送给DBA,实现实时监控效果。
下面是对前面提到的几个常见错误的描述:
小结
通过上面这11种方法对Oracle监听器进行保护后,想要通过监听器进行破坏活动基本上就很困难了,不能保证100%拦截攻击,也至少有99%的效果,另外那1%可能就是DBA本身犯的一些低级错误了,如不小心将监听器密码泄露给他人,或将配置信息暴露在Internet上。
1、DNS端口号是域名系统 (Domain Name System)
的缩写,该系统用于命名组织到域层次结构中的计算机和网络服务。在Internet上域名与IP地址之间是一一对应的,域名虽然便于人们记忆,但机器之间
只能互相认识IP地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成。
2、DNS协议运行在UDP协议之上,使用端口号53。
1Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。
2MQTT协议是应用层协议不依赖长连接,适合弱网络。通过topic缓存信息。符合物联网设备的使用场景。因为通过topic缓存信息,因此可以实现通过topic与多个端的一对多连接,而不是设备与设备的多对多连接,节省了能耗及带宽。
MQTT的心跳,及非信息的报文,较Websocket更少,更节省带宽及能耗。更适用于物理网的多种网络协议。
3WebSocket和Http一样在应用层,提供使用一个TCP连接进行双向通讯的机制,包括网络协议和API,以取代网页和服务器采用HTTP轮询进行双向通讯的机制。 本质上来说,WebSocket是不限于HTTP协议的,但是由于现存大量的HTTP基础设施,代理,过滤,身份认证等等,WebSocket借用HTTP和HTTPS的端口。由于使用HTTP的端口,因此TCP连接建立后的握手消息是基于HTTP的,由服务器判断这是一个HTTP协议,还是WebSocket协议。 WebSocket连接除了建立和关闭时的握手,数据传输和HTTP没丁点关系了。
Socket 连接,至少需要一对套接字,分为 clientSocket,serverSocket 连接分为3个步骤:
(1) 服务器监听:服务器并不定位具体客户端的套接字,而是时刻处于监听状态;
(2) 客户端请求:客户端的套接字要描述它要连接的服务器的套接字,提供地址和端口号,然后向服务器套接字提出连接请求;
(3) 连接确认:当服务器套接字收到客户端套接字发来的请求后,就响应客户端套接字的请求,并建立一个新的线程,把服务器端的套接字的描述发给客户端。一旦客户端确认了此描述,就正式建立连接。而服务器套接字继续处于监听状态,继续接收其他客户端套接字的连接请求
Socket为长连接:通常情况下Socket 连接就是 TCP 连接,因此 Socket 连接一旦建立,通讯双方开始互发数据内容,直到双方断开连接。在实际应用中,由于网络节点过多,在传输过程中,会被节点断开连接,因此要通过轮询高速网络,该节点处于活跃状态。
很多情况下,都是需要服务器端向客户端主动推送数据,保持客户端与服务端的实时同步。
若双方是 Socket 连接,可以由服务器直接向客户端发送数据。
若双方是 HTTP 连接,则服务器需要等客户端发送请求后,才能将数据回传给客户端。
因此,客户端定时向服务器端发送请求,不仅可以保持在线,同时也询问服务器是否有新数据,如果有就将数据传给客户端。
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是轻量级基于代理的发布/订阅的消息传输协议,设计思想是开放、简单、轻量、易于实现。这些特点使它适用于受限环境。
例如:
①网络代价昂贵,带宽低、不可靠。
②在嵌入设备中运行,处理器和内存资源有限。
该协议的特点有:
①使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。 ②对负载内容屏蔽的消息传输。
③使用 TCP/IP 提供网络连接。
④有三种消息发布服务质量:
⑤"至多一次",消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
⑥"至少一次",确保消息到达,但消息重复可能会发生。
⑦"只有一次",确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
⑧小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。
⑨使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制。
实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
有三种消息发布服务质量:
“至多一次”,消息发布完全依赖底层TCP/IP网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。这一种方式主要普通APP的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就收不到了。qos=0
“至少一次”,确保消息到达,但消息重复可能会发生。qos=1
“只有一次”,确保消息到达一次。在一些要求比较严格的计费系统中,可以使用此级别。在计费系统中,消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送,确保用户收到且只会收到一次。qos=2
Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload);
payload,可以理解为消息的内容,是指订阅者具体要使用的内容。
在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、可变头(Variable header)、消息体(payload)三部分构成。MQTT数据包结构如下:
固定头(Fixed header)。存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识。
可变头(Variable header)。存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。
消息体(Payload)。存在于部分MQTT数据包中,表示客户端收到的具体内容。
WebSocket则提供使用一个TCP连接进行双向通讯的机制,包括网络协议和API,以取代网页和服务器采用HTTP轮询进行双向通讯的机制。 本质上来说,WebSocket是不限于HTTP协议的,但是由于现存大量的HTTP基础设施,代理,过滤,身份认证等等,WebSocket借用HTTP和HTTPS的端口。由于使用HTTP的端口,因此TCP连接建立后的握手消息是基于HTTP的,由服务器判断这是一个HTTP协议,还是WebSocket协议。 WebSocket连接除了建立和关闭时的握手,数据传输和HTTP没丁点关系了。 由此可知两者的应用场景不一样: MQTT是为了物联网场景设计的基于TCP的Pub/Sub协议,有许多为物联网优化的特性,比如适应不同网络的QoS、层级主题、遗言等等。 WebSocket是为了HTML5应用方便与服务器双向通讯而设计的协议,HTTP握手然后转TCP协议,用于取代之前的Server Push、Comet、长轮询等老旧实现。 两者之所有有交集,是因为一个应用场景:如何通过HTML5应用来作为MQTT的客户端,以便接受设备消息或者向设备发送信息,那么MQTT over WebSocket自然成了最合理的途径了。
可以考虑用JAVA实现监听客户端口,参考例子如下:
package test;import javaioByteArrayOutputStream;
import javaioIOException;
import javaioInputStream;
import javaioOutputStream;
import javalangreflectMethod;
import javanetDatagramPacket;
import javanetDatagramSocket;
import javanetInetAddress;
import javanetServerSocket;
import javanetSocket;
import javanetSocketException;
import javautilHashMap;
import javautilLinkedList;
import javautilList;
import javautilRandom;
/
该程序用的DatagramSocket,实现UDP的通讯
@author D'Addario
/
public class Test{
private int headLen = 12;//消息起点和终点的记录 例如classAclassB就是发往classA的消息,发送者是classB
private Random random;
private String serverIp;
private int serverPort;
private HashMap<String,Classes> map ;
{
serverIp = "127001";
serverPort = 9999;
random = new Random(SystemcurrentTimeMillis());
map = new HashMap<String,Classes>();
Classes A = Testthisnew Classes();
Aip = "127001";
Aname = "我是A";
Aport = 10000;
mapput("classA", A);
Classes B = Testthisnew Classes();
Bip = "127001";
Bname = "我是B";
Bport = 10001;
mapput("classB", B);
}
public static void main(String[] a) throws Exception{
Test test = new Test();
new Thread(testnew Server())start();
Client client1 = testnew Client();
client1mine = "classA";
client1remote = "classB";
new Thread(client1)start();
Client client2 = testnew Client();
client2mine = "classB";
client2remote = "classA";
new Thread(client2)start();
}
/
成员 用于记录 每个成员的个性信息
@author D'Addario
/
private class Classes {
private String name ; //成员姓名
private String ip ; //成员ip
private int port;//成员的client server 监听端口
}
/
server 用于转发两个client之间消息的类
@author D'Addario
/
private class Server implements Runnable{
public void run() {
// TODO Auto-generated method stub
boolean start = false;
DatagramSocket socket = null;
try {
socket = new DatagramSocket(serverPort);
start = true;
} catch (SocketException e1) {
e1printStackTrace();
}
while(start)
{
try {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data,datalength);
socketreceive(packet);
int len = packetgetLength();
//Systemoutprintln("recevie data:"+new String(data,0,len));
if(len<headLen)
throw new IOException("无效数据");
String id = new String(data,0,headLen/2);//获取发往对象的ID
String id2 = new String(data,headLen/2,headLen/2);
Systemoutprintln("receive from "+id2 +", send to "+id+",msg["+new String(data,headLen,len-headLen)+"]");
Classes one = mapget(idtrim());
DatagramPacket retPack = new DatagramPacket(data,0,len,InetAddressgetByName(oneip),oneport);
socketsend(retPack);
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}
}
}
/
Client 客户端类,用于客户端消息的发送
@author D'Addario
/
private class Client implements Runnable{
private String mine;
private String remote;
public void run() {
// TODO Auto-generated method stub
String msg = remote+mine;
DatagramSocket socket = null;
try {
socket = new DatagramSocket(mapget(mine)port);
ClientServer srv=new ClientServer();
srvsetSocket(socket);
new Thread(srv)start();
} catch (SocketException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
byte[] data ;
while(true)
{
String sendStr = msg + "给我"+randomnextInt(5000)+"分吧";
data = sendStrgetBytes();
try {
DatagramPacket retPack = new DatagramPacket(data,0,datalength,InetAddressgetByName(serverIp),serverPort);
socketsend(retPack);
Threadsleep(randomnextInt(5)1000);
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}
}
}
/
客户端server 用于监听服务器的消息
@author D'Addario
/
private class ClientServer implements Runnable{
DatagramSocket socket ;
public DatagramSocket getSocket() {
return socket;
}
public void setSocket(DatagramSocket socket) {
thissocket = socket;
}
public void run() {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data,datalength);
while(true){
try {
socketreceive(packet);
int len = packetgetLength();
if(len<headLen)
throw new IOException("无效数据");
Systemoutprintln("I get the message :"+ThreadcurrentThread()getId()+"-->["+new String(data,0,len)+"]");
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
} }
}
}
}
0条评论