Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/act365/net/tcp/TCPWriter.java


1   /*
2     * JSocket Wrench
3     * 
4     * Copyright (C) act365.com October 2003
5     * 
6     * Web site: http://www.act365.com/wrench
7     * E-mail: developers@act365.com
8     * 
9     * The JSocket Wrench library adds support for low-level Internet protocols
10    * to the Java programming language.
11    * 
12    * This program is free software; you can redistribute it and/or modify it 
13    * under the terms of the GNU General Public License as published by the Free 
14    * Software Foundation; either version 2 of the License, or (at your option) 
15    * any later version.
16    *  
17    * This program is distributed in the hope that it will be useful, 
18    * but WITHOUT ANY WARRANTY; without even the implied warranty of 
19    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 
20    * Public License for more details.
21    * 
22    * You should have received a copy of the GNU General Public License along with 
23    * this program; if not, write to the Free Software Foundation, Inc., 
24    * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25    */
26  
27  package com.act365.net.tcp ;
28  
29  import com.act365.net.* ;
30  
31  /**
32   * Writes TCP messages to a bytestream.
33   */
34  
35  public class TCPWriter {
36  
37    static byte[] write( TCPMessage message ){
38  
39      int length = 20 + message.options.length + message.data.length ;
40  
41      byte[] buffer = new byte[ length ];
42  
43      SocketUtils.shortToBytes( message.sourceport , buffer , 0 );
44      SocketUtils.shortToBytes( message.destinationport , buffer , 2 );
45      SocketUtils.intToBytes( message.sequencenumber , buffer , 4 );
46      SocketUtils.intToBytes( message.acknowledgementnumber , buffer , 8 );
47      
48      buffer[ 12 ] = (byte)( message.headerlength << 4 );
49      buffer[ 13 ] = 0 ;
50  
51      if( message.urg ) buffer[ 13 ] |= TCP.URG ;
52      if( message.ack ) buffer[ 13 ] |= TCP.ACK ;
53      if( message.psh ) buffer[ 13 ] |= TCP.PSH ;
54      if( message.rst ) buffer[ 13 ] |= TCP.RST ;
55      if( message.syn ) buffer[ 13 ] |= TCP.SYN ;
56      if( message.fin ) buffer[ 13 ] |= TCP.FIN ;
57  
58      SocketUtils.shortToBytes( message.windowsize , buffer , 14 );
59      SocketUtils.shortToBytes( message.checksum , buffer , 16 );
60      SocketUtils.shortToBytes( message.urgentpointer , buffer , 18 );
61  
62      int i = 20 ;
63  
64      while( i < 20 + message.options.length ){
65        buffer[ i ] = message.options[ i - 20 ];
66        ++ i ;
67      }
68  
69      while( i < length ){
70        buffer[ i ] = message.data[ i - 20 - message.options.length ];
71        ++ i ;
72      }
73  
74      return buffer ;
75    }
76  
77    /**
78     * Writes a TCP message to a bytestream.
79     */
80  
81    public static byte[] write( byte[] sourceaddress ,
82                                short sourceport ,
83                                byte[] destinationaddress ,
84                                short destinationport ,
85                                int sequencenumber ,
86                                int acknowledgementnumber ,
87                                boolean ack ,
88                                boolean rst ,
89                                boolean syn ,
90                                boolean fin ,
91                                boolean psh ,
92                                short windowsize ,
93                                TCPOptions options ,
94                                byte[] data ,
95                                int offset ,
96                                int count ){
97    
98      TCPMessage message = new TCPMessage();
99  
100     message.sourceport = sourceport ;
101     message.destinationport = destinationport ;
102     message.sequencenumber = sequencenumber ;
103     message.acknowledgementnumber = acknowledgementnumber ;
104     message.headerlength = 5 ;
105     message.urg = false ;
106     message.ack = ack ;
107     message.psh = psh ;
108     message.rst = rst ;
109     message.syn = syn ;
110     message.fin = fin ;
111     message.windowsize = windowsize ; 
112     message.checksum = 0 ;
113     message.urgentpointer = 0 ;
114 
115     byte[] optionsbuffer = new byte[ 128 ];
116 
117     int cursor = 0 ;
118 
119     if( options.isMaxSegmentSizeSet() ){
120       optionsbuffer[ cursor ] = 2 ;
121       optionsbuffer[ cursor + 1 ] = 4 ;
122       SocketUtils.shortToBytes( options.getMaxSegmentSize() , optionsbuffer , cursor + 2 );
123       cursor += 4 ;
124     }
125  
126     if( options.isWindowScaleFactorSet() ){
127       optionsbuffer[ cursor ] = 1 ;
128       optionsbuffer[ cursor + 1 ] = 3 ;
129       optionsbuffer[ cursor + 2 ] = 3 ;
130       optionsbuffer[ cursor + 3 ] = options.getWindowScaleFactor() ;
131       cursor += 4 ;
132     }
133 
134     if( options.isTimestampSet() ){
135       optionsbuffer[ cursor ] = 1 ;
136       optionsbuffer[ cursor + 1 ] = 1 ;
137       optionsbuffer[ cursor + 2 ] = 8 ;
138       optionsbuffer[ cursor + 3 ] = 10 ;
139       SocketUtils.intToBytes( options.getTimestampValue() , optionsbuffer , cursor + 4 );
140       SocketUtils.intToBytes( options.getTimestampEchoReply() , optionsbuffer , cursor + 8 );
141       cursor += 12 ;
142     }
143 
144     message.headerlength += cursor / 4 ; 
145     message.options = new byte[ cursor ];
146 
147     int i = -1 ;
148 
149     while( ++ i < cursor ){
150       message.options[ i ] = optionsbuffer[ i ];
151     }
152 
153     message.data = new byte[ count ];
154 
155     i = -1 ;
156 
157     while( ++ i < count ){
158       message.data[ i ] = data[ i + offset ];
159     }
160       
161     short length = (short)( 4 * message.headerlength + count );
162 
163     message.checksum = SocketUtils.checksum( sourceaddress ,
164                                                    destinationaddress ,
165                                                    (byte) SocketConstants.IPPROTO_TCP ,
166                                                    length ,
167                                                    write( message ) ,
168                                                    0 );
169 
170     return write( message );
171   }
172 }    
173