暂时还没看出问题来,可以测试一下
1、判断getpeername的返回值,若有错误,把错误代码打印出来;
2、wsprintf函数是针对UNICODE字符的吧?为什么不用sprintf
3、你的备注里说因为网络传送是低位先传送,正确的应该是网络字节序和主机字节序的问题,在网络上使用网络字节序,是高位先存。主机字节序其实又包括大端和小端,而htons, htonl, inet_addr, inet_ntoa, inet_ntol这些函数就是用于实现主机字节序和网络字节序的转换的,这些函数内部会根据大端还是小端来决定如何将数值转换成网络字节序。
你是想知道代码还是想了解原理,一般的C/S模型都由客户端发出连接请求(客户端在代码中都是存有服务器端的具体ip地址和端口信息(也就是服务器端的INET协议族地址结构)的),当客户端发送连接请求后,服务器端通过accpet函数接收连接请求,accpet函数示例:accept(ServerSocket,(structsockaddr)&from,&len)(from是一个INET协议族地址结构变量,(structsockaddr)的作用是把INET协议族地址结构强制转换为通用地址结构),accpet函数在接收连接的同时会把客户端的具体ip和端口信息赋值给from,所以说客户端socket连接的ip(非绑定的话客户机随机绑定ip和端口)是包含在连接报文数据里,服务器端只有接收到客户端发送的连接信息后,才会获得客户端的ip和端口信息,获得具体ip的方式是通过函数,这个函数可以提取出IPv4地址结构中的点分十进制地址,函数用法:inet_ntoa(fromsin_addr)。
通过计算机名称获得ip
SystemNetIPAddress[] addresses = SystemNetDnsGetHostAddresses ( ">
首先你需要解析外部传进来的数据包,正常情况下,通信数据包的包头已经包含了数据包的源端和目的端地址。目的端地址自然是你的IP地址,而你所要做的就是对源端地址进行判断。
如果源端地址是你指定的,那就解析数据包的净载荷部分(payload),进行相应的处理;
若不是你指定的,那么就不要处理,直接丢弃就好了。
这部分设计到socket底层编程,我以前用C#编写过,完全可以实现。
java获取固定IP发来所有的数据包,需要实现网络嗅探的部分功能:
代码如下;
/JpcapTipjava
/
package m;
import jpcapPacketReceiver;
import jpcapJpcapCaptor;
import jpcappacket;
import jpcapNetworkInterface;
import jpcapNetworkInterfaceAddress;
//import javanetInetAddress;
//import javanetUnknownHostException;
public class JpcapTip implements PacketReceiver {
public void receivePacket(Packet packet) {
Systemoutprintln("");
/IP数据报报文头/
byte[] l=packetheader;
/
for (int t=0;t<21;t++){
Systemoutprint(l[t]+" ");
}
/
String str="";
Systemoutprint("报文头 : ");
for (int i=0;i<llength;i++) {
//str=str+l;
int m=0;
m=l[i];
m=m<<24;
m=m>>>24;
str=str+IntegertoHexString(m);
//Systemoutprint(" "+l[i]);
}
Systemoutprintln(str);
int d=llength;
Systemoutprintln("首部长度 :"+(d8)+"bit");
/分析源IP地址和目的IP地址/
/分析协议类型/
/
if(packetgetClass()equals(IPPacketclass)) {
IPPacket ipPacket=(IPPacket)packet;
byte[] iph=ipPacketoption;
String iphstr=new String(iph);
Systemoutprintln(iphstr);
}
/
if(packetgetClass()equals(ARPPacketclass))
{
Systemoutprintln("协议类型 :ARP协议");
try {
ARPPacket arpPacket = (ARPPacket)packet;
Systemoutprintln("源网卡MAC地址为 :"+arpPacketgetSenderHardwareAddress());
Systemoutprintln("源IP地址为 :"+arpPacketgetSenderProtocolAddress());
Systemoutprintln("目的网卡MAC地址为 :"+arpPacketgetTargetHardwareAddress());
Systemoutprintln("目的IP地址为 :"+arpPacketgetTargetProtocolAddress());
} catch( Exception e ) {
eprintStackTrace();
}
}
else
if(packetgetClass()equals(UDPPacketclass))
{
Systemoutprintln("协议类型 :UDP协议");
try {
UDPPacket udpPacket = (UDPPacket)packet;
Systemoutprintln("源IP地址为 :"+udpPacketsrc_ip);
int tport = udpPacketsrc_port;
Systemoutprintln("源端口为:"+tport);
Systemoutprintln("目的IP地址为 :"+udpPacketdst_ip);
int lport = udpPacketdst_port;
Systemoutprintln("目的端口为:"+lport);
} catch( Exception e ) {
eprintStackTrace();
}
}
else
if(packetgetClass()equals(TCPPacketclass)) {
Systemoutprintln("协议类型 :TCP协议");
try {
TCPPacket tcpPacket = (TCPPacket)packet;
int tport = tcpPacketsrc_port;
Systemoutprintln("源IP地址为 :"+tcpPacketsrc_ip);
Systemoutprintln("源端口为:"+tport);
Systemoutprintln("目的IP地址为 :"+tcpPacketdst_ip);
int lport = tcpPacketdst_port;
Systemoutprintln("目的端口为:"+lport);
} catch( Exception e ) {
eprintStackTrace();
}
}
else
if(packetgetClass()equals(ICMPPacketclass))
Systemoutprintln("协议类型 :ICMP协议");
else
Systemoutprintln("协议类型 :GGP、EGP、JGP协议或OSPF协议或ISO的第4类运输协议TP4");
/IP数据报文数据/
byte[] k=packetdata;
String str1="";
Systemoutprint("数据 : ");
for(int i=0;i<klength;i++) {
//int m=0;
//m=k[i];
//m=m<<24;
//m=m>>>24;
//str1=str+IntegertoHexString(m);
str1 = new String(k);
//str1=str1+k[i];
//Systemoutprint(" "+k[i]);
}
Systemoutprintln(str1);
Systemoutprintln("数据报类型 : "+packetgetClass());
Systemoutprintln("");
}
public static void main(String[] args) throws Exception{
// TODO 自动生成方法存根
NetworkInterface[] devices = JpcapCaptorgetDeviceList(); //getDeviceList();
//for (int i =0; i<deviceslength;i++) {
int a=0;
//try {
/本地网络信息/
byte[] b=devices[1]mac_address; //网卡物理地址
//}
//catch() {}
Systemoutprint("网卡MAC : 00");
for (int j=0;j<blength;j++){
//a=a<<8;
a=b[j];
a=a<<24;
a=a>>>24;
Systemoutprint(IntegertoHexString(a));
}
Systemoutprintln();
NetworkInterfaceAddress[] k=devices[1]addresses;
//Systemoutprintln("网卡MAC : "+IntegertoHexString(a));
for(int n=0;n<klength;n++) {
Systemoutprintln("本机IP地址 : "+k[n]address); //本机IP地址
Systemoutprintln("子网掩码 : "+k[n]subnet); //子网掩码
}
Systemoutprintln("网络连接类型 : "+devices[1]datalink_description);
//}
NetworkInterface deviceName = devices[1];
/将网卡设为混杂模式下用网络设备deviceName/
JpcapCaptor jpcap =JpcapCaptoropenDevice(deviceName, 2000, false, 1); //openDevice(deviceName,1028,false,1);
jpcaploopPacket(-1,new JpcapTip());
}
}
计算机网络相关的问题,如果想去了解,前提就是深刻理解网络4/7层模型。
记住并理解,上面每一层。切记,切记,切记。知道一些就可以开始主题,分两个部分TCP和Socket。
TCP是(Tranfer Control Protocol)的简称,在OSI参考模型第四层,也就是端口,到端口的的通信,它是一个可靠的双向连接,一旦建立连接就可以双向数据传输,双方都可以进行发送或接收 *** 作。
最常听说的就是三次握手。是的它说的就是TCP建立连接的过程。具体的步骤如下:
第一步:Server监听端口,状态为:Listen
第二部:Client发送SNY包,请求连接,并将状态改为:SYN_SEND
第三部:Server发送ACK包,和SNY包,同意,并请求连接,状态改为:SYN_RCVD
第四部:Client发送ACK包,Server收到包后,连接建立。双方状态改为:ESTABLISHED
第一步:Client发起FIN包。状态变为:FNI_WAIT_1
第二步:Server发送ACK包。状态变为:CLOSE_WAIT,Client收包后状态变为:FNI_WAIT_2
第三步:Server发送FIN包,状态变为:LAST_ACK。Client收包后状态变为:TIME_WAIT
第四步:Client发送ACK包。双方状态变为:CLOSED
需要注意的是,Client是在收到Server FIN包后两个最大报文时间(2MSL)后变为CLOSED状态的。双方都可以发起断开请求,上面是已先发起请求的是Client。
如何验证上面讲的这些呢?那就是抓包分析,其实日常的开发中也可以通过抓包来发现问题。在这里我简单贴个图看一下TCP的包,这个工具非常强大感兴趣的朋友可以去深入了解一下。
1可以在这个过滤,通过协议,通过IP,通过端口都可以。
2这个就是每个包,例子中的这个是个[SYN,ACK]包,就是建立TCP连接的第二次握手
3被抓取的包对应的网络层,从上到下分别是:物理层、数据链路层、网络层、传输层。
Socket其实就是TCP协议的实现。也就是说它就是TCP的API,当然其实Socket也支持别的协议如:UDP。既然是API那,上面说的其实就是它的原理。下面说一下它的使用。大概说一下。
1ServerSocket:是服务端来监听的类。监听方法accept()。
2客户端:创建Socket对象,设定IP和Port
3当有新的客户端连接时可以通过ServerSocket类获取Socket。而Socket就是我们的通讯渠道。
4发送和读取数据分别使用OutputStream和InputStream而这两个类是从Socket获取的。
其实Socket的基本使用就是这么简单,但是在其实项目中这样是无法满足需求的。实际上大多数场景都是需要一对多的提供服务。
使用多线程实现多客户端的通信
实现服务器与多个客户端进行通信, 可以接受多个客户端的请求并进行回复
应用多线程来实现服务器与多客户端之间的通信
1、服务器端创建ServerSocket,循环调用accept()等待客户端连接
2、客户端创建一个Socket并请求和服务器端连接
3、服务器端接受客户端请求,创建socket与该客户建立专线连接
4、建立连接的两个socket在一个单独的线程上对话
5、服务器端继续等待新的连接
负载平衡负载均衡是由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助。通过某种负载分担技术,将外部发送来的请求均匀分配到对称结构中的某一台服务器上,而接收到请求的服务器独立地回应客户的请求。均衡负载能够平均分配客户请求到服务器列阵,籍此提供快速获取重要数据,解决大量并发访问服务问题。这种群集技术可以用最少的投资获得接近于大型主机的性能。网络负载均衡的优点第一,网络负载均衡能将传入的请求传播到多达32台服务器上,即可以使用最多32台服务器共同分担对外的网络请求服务。网络负载均衡技术保证即使是在负载很重的情况下,服务器也能做出快速响应;第二,网络负载均衡对外只需提供一个IP地址(或域名);第三,当网络负载均衡中的一台或几台服务器不可用时,服务不会中断。网络负载均衡自动检测到服务器不可用时,能够迅速在剩余的服务器中重新指派客户机通讯。这项保护措施能够帮助你为关键的业务程序提供不中断的服务,并可以根据网络访问量的增加来相应地增加网络负载均衡服务器的数量;第四,网络负载均衡可在普通的计算机上实现。网络负载均衡的实现过程在WindowsServer2003中,网络负载均衡的应用程序包括Internet信息服务(IIS)、ISAServer2000防火墙与代理服务器、***虚拟专用网、终端服务器、WindowsMediaServices(Windows视频点播、视频广播)等服务。同时,网络负载均衡有助于改善服务器的性能和可伸缩性,以满足不断增长的基于Internet客户端的需求。网络负载均衡可以让客户端用一个逻辑Internet名称和虚拟IP地址(又称群集IP地址)访问群集,同时保留每台计算机各自的名称。下面,我们将在两台安装WindowsServer2003的普通计算机上,介绍网络负载均衡的实现及应用。这两台计算机中,一台计算机名称为A,IP地址为19216807;另一台名为B,IP地址为19216808。规划网络负载均衡专用虚拟IP地址为19216809。当正式应用时,客户机只需要使用IP地址19216809来访问服务器,网络服务均衡会根据每台服务器的负载情况自动选择19216807或者19216808对外提供服务。具体实现过程如下:在实现网络负载均衡的每一台计算机上,只能安装TCP/IP协议,不要安装任何其他的协议(如IPX协议或者NetBEUI协议),这可以从“网络连接属性”中查看。第一步,分别以管理员身份登录A机和B机,打开两台机的“本地连接”属性界面,勾选“此连接使用下列项目”中的“负载均衡”项并进入“属性”对话框,将IP地址都设为19216809(即负载均衡专用IP),将子网掩码设置为2552552550;第二步,分别进入A机和B机的“Internet协议(TCP/IP)”属性设置界面,点击“高级”按钮后,在d出的“高级TCP/IP设置”界面中添加IP地址19216809和子网掩码设置为2552552550。第三步,退出两台计算机的“本地连接属性”窗口,耐心等一会儿让系统完成设置。以后,如果这两台服务器不能满足需求,可以按以上步骤添加第三台、第四台计算机到网络负载均衡系统中以满足要求。编辑词条
以上就是关于通过SOCKET句柄获取连接客户端的IP和端口的问题!全部的内容,包括:通过SOCKET句柄获取连接客户端的IP和端口的问题!、怎么获取socket ip 地址、关于SOCKET接收网上邻居的计算机获取相对应IP的问题求解。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)