tcpprotocol.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 198 行
JAVA
198 行
/*
* $Id: TCPProtocol.java,v 1.1 2003/11/25 11:52:23 epr Exp $
*/
package org.jnode.net.ipv4.tcp;
import java.io.IOException;
import java.net.BindException;
import java.net.DatagramSocketImplFactory;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketImplFactory;
import org.apache.log4j.Logger;
import org.jnode.driver.net.NetworkException;
import org.jnode.net.SocketBuffer;
import org.jnode.net.ipv4.IPv4Address;
import org.jnode.net.ipv4.IPv4Constants;
import org.jnode.net.ipv4.IPv4Header;
import org.jnode.net.ipv4.IPv4Protocol;
import org.jnode.net.ipv4.IPv4Service;
import org.jnode.util.Statistics;
/**
* @author epr
*/
public class TCPProtocol implements IPv4Protocol, IPv4Constants, TCPConstants {
/** The IP service I'm a part of */
private final IPv4Service ipService;
/** The ICMP service */
//private final ICMPUtils icmp;
/** My statistics */
private final TCPStatistics stat = new TCPStatistics();
/** The SocketImpl factory for TCP */
private final TCPSocketImplFactory socketImplFactory;
/** My control blocks */
private final TCPControlBlockList controlBlocks;
/** The timer */
private final TCPTimer timer;
/** My logger */
private final Logger log = Logger.getLogger(getClass());
/**
* Initialize a new instance
*
* @param ipService
*/
public TCPProtocol(IPv4Service ipService) throws NetworkException {
this.ipService = ipService;
//this.icmp = new ICMPUtils(ipService);
this.controlBlocks = new TCPControlBlockList(this);
this.timer = new TCPTimer(controlBlocks);
try {
socketImplFactory = new TCPSocketImplFactory(this);
Socket.setSocketImplFactory(socketImplFactory);
ServerSocket.setSocketFactory(socketImplFactory);
} catch (IOException ex) {
throw new NetworkException(ex);
}
timer.start();
}
/**
* @see org.jnode.net.TransportLayer#getDatagramSocketImplFactory()
*/
public DatagramSocketImplFactory getDatagramSocketImplFactory() throws SocketException {
throw new SocketException("TCP is socket based");
}
/**
* @see org.jnode.net.TransportLayer#getName()
*/
public String getName() {
return "tcp";
}
/**
* @see org.jnode.net.TransportLayer#getProtocolID()
*/
public int getProtocolID() {
return IPPROTO_TCP;
}
/**
* @see org.jnode.net.TransportLayer#getSocketImplFactory()
*/
public SocketImplFactory getSocketImplFactory() throws SocketException {
return socketImplFactory;
}
/**
* @see org.jnode.net.TransportLayer#getStatistics()
*/
public Statistics getStatistics() {
return stat;
}
/**
* @see org.jnode.net.TransportLayer#receive(org.jnode.net.SocketBuffer)
*/
public void receive(SocketBuffer skbuf) throws SocketException {
// Increment stats
stat.ipackets.inc();
// Get the IP header
final IPv4Header ipHdr = (IPv4Header) skbuf.getNetworkLayerHeader();
// Read the TCP header
final TCPHeader hdr = new TCPHeader(skbuf);
// Set the TCP header in the buffer-field
skbuf.setTransportLayerHeader(hdr);
// Remove the TCP header from the head of the buffer
skbuf.pull(hdr.getLength());
// Trim the buffer up to the length in the TCP header
skbuf.trim(hdr.getDataLength());
if (!hdr.isChecksumOk()) {
if (log.isDebugEnabled()) {
log.debug("Receive: badsum: " + hdr);
}
stat.badsum.inc();
} else {
if (log.isDebugEnabled()) {
log.debug("Receive: " + hdr);
}
// Find the corresponding control block
final TCPControlBlock cb = (TCPControlBlock) controlBlocks.lookup(ipHdr.getSource(), hdr.getSrcPort(), ipHdr.getDestination(), hdr.getDstPort(), true);
if (cb == null) {
// Port unreachable
log.debug("Port unreachable");
stat.noport.inc();
processPortUnreachable(ipHdr, hdr);
} else {
// Let the cb handle the receive
cb.receive(hdr, skbuf);
}
}
}
/**
* @see org.jnode.net.ipv4.IPv4Protocol#receiveError(org.jnode.net.SocketBuffer)
*/
public void receiveError(SocketBuffer skbuf) throws SocketException {
// TODO Auto-generated method stub
}
/**
* Process a segment whose destination port is unreachable
*
* @param hdr
*/
private void processPortUnreachable(IPv4Header ipHdr, TCPHeader hdr) throws SocketException {
final TCPHeader replyHdr = new TCPHeader(hdr.getDstPort(), hdr.getSrcPort(), 0, 0, hdr.getSequenceNr() + 1, 0, 0);
replyHdr.setFlags(TCPF_ACK | TCPF_RST);
final IPv4Header replyIpHdr = new IPv4Header(ipHdr);
replyIpHdr.swapAddresses();
send(replyIpHdr, replyHdr, new SocketBuffer());
}
/**
* Create a binding for a local address
*
* @param lAddr
* @param lPort
*/
public TCPControlBlock bind(IPv4Address lAddr, int lPort) throws BindException {
return (TCPControlBlock) controlBlocks.bind(lAddr, lPort);
}
/**
* Send an TCP packet
*
* @param skbuf
*/
protected void send(IPv4Header ipHdr, TCPHeader tcpHdr, SocketBuffer skbuf) throws SocketException {
if (log.isDebugEnabled()) {
log.debug("send(ipHdr, " + tcpHdr + ")");
}
skbuf.setTransportLayerHeader(tcpHdr);
tcpHdr.prefixTo(skbuf);
ipHdr.setDataLength(skbuf.getSize());
ipService.transmit(ipHdr, skbuf);
stat.opackets.inc();
}
/**
* Get the current time counter
*/
protected long getTimeCounter() {
return timer.getCounter();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?