TCP/IP 四层参考模型
-- 应用层
-- 传输层
-- 网络互联曾
-- 网络接入层
数据链路层MTU为1500,不包括链路层的头部和尾部,所以1500指的是数据的大小,
不包括头部的源地址6字节、目的地址6字节,还有类型字段2字节。以及尾部的CRC校验码4字节
然后去掉TCP头部20字节(通常)和IP头部字节(通常),所以TCP的MSS大小通常设置为1460
UDP里有数据报长度字段,16位,所以UDP数据最大64KB.
InetAddress
-- Inet4Address
-- Inet6Address
1.UDP:
DatagramSocket 发送接收数据包
DatagramPacket UDP数据包
发送数据步骤:
1)构建socket,监听端口
2)构建数据包
3)发送数据包
1)构建socket,监听端口
2)构建接收数据包
3)接收数据
4)关闭服务
2.TCP:
客户端 Socket
服务端 ServerSocket
客户端连接:
1) 创建socket服务,指定要连接的服务器的地址和端口号
2) 获取IO对象。getInputStream(), getOutputStream()
服务器连接:ServerSocket
1) 建立ServerSocket对象,关联端口号
2) 获取连接过来的客户端对象 Socket 对象, 通过 accept();
3) 读取数据
PS1:
一个重要的问题,TCP 客户端和服务端传输数据的时候,
bufferedWriter一定要加回车符,即newLine(),以及flush()。
因为BufferedReader只有读到回车符,才会返回数据。
PS2:TCP传输的时候一定要考虑结束标记,通常关闭客户端输出流,shutdownOutput()
在发送数据前先发送一个时间戳给服务端
3. 具体小实例
1) UDP:
import java.net.*;
import java.io.*;
import java.lang.*;
class Send implements Runnable
{
public void run()
{
try
{
DatagramSocket ds = new DatagramSocket(10001);
byte[] data;
String s = null;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while((s=br.readLine())!=null)
{
if(s.equals("88"))
break;
data = s.getBytes();
DatagramPacket dp =
new DatagramPacket(data,data.length,
InetAddress.getByName("192.168.1.102"),10000);
ds.send(dp);
}
ds.close();
}
catch (Exception e)
{
}
}
}
class Rec implements Runnable
{
public void run()
{
try
{
DatagramSocket ds = new DatagramSocket(10000);
byte[] data = new byte[1024];
while(true)
{
DatagramPacket dp = new DatagramPacket(data,data.length);
ds.receive(dp);
String s = new String(data,0,dp.getLength());
System.out.println(dp.getAddress().getHostName()+"..."
+dp.getAddress().getHostAddress()+":"+s);
if(s.equals("88"))
break;
}
ds.close();
}
catch (Exception e)
{
}
}
}
class UDPDemo
{
public static void main(String[] args)
{
new Thread(new Send()).start();
new Thread(new Rec()).start();
}
}
2)TCP:
import java.io.*;
import java.net.*;
class TCPClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.102",20000);
String line = null;
String readLine = null;
BufferedReader brin = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bwout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader brinput = new BufferedReader(new InputStreamReader(s.getInputStream()));
while((line=brin.readLine())!=null)
{
if(line.equals("88"))
break;
bwout.write(line);
bwout.newLine();
bwout.flush();
readLine=brinput.readLine();
System.out.println(readLine);
}
s.close();
brin.close();
}
}
class TCPServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(20000);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+"connected");
BufferedReader brin = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter brout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while((line=brin.readLine())!=null)
{
if(line.equals("88"))
break;
System.out.println(line);
brout.write(line.toUpperCase());
brout.newLine();
brout.flush();
}
s.close();
ss.close();
}
}
-- 应用层
-- 传输层
-- 网络互联曾
-- 网络接入层
数据链路层MTU为1500,不包括链路层的头部和尾部,所以1500指的是数据的大小,
不包括头部的源地址6字节、目的地址6字节,还有类型字段2字节。以及尾部的CRC校验码4字节
然后去掉TCP头部20字节(通常)和IP头部字节(通常),所以TCP的MSS大小通常设置为1460
UDP里有数据报长度字段,16位,所以UDP数据最大64KB.
InetAddress
-- Inet4Address
-- Inet6Address
1.UDP:
DatagramSocket 发送接收数据包
DatagramPacket UDP数据包
发送数据步骤:
1)构建socket,监听端口
2)构建数据包
3)发送数据包
4)关闭服务
1)构建socket,监听端口
2)构建接收数据包
3)接收数据
4)关闭服务
2.TCP:
客户端 Socket
服务端 ServerSocket
客户端连接:
1) 创建socket服务,指定要连接的服务器的地址和端口号
2) 获取IO对象。getInputStream(), getOutputStream()
服务器连接:ServerSocket
1) 建立ServerSocket对象,关联端口号
2) 获取连接过来的客户端对象 Socket 对象, 通过 accept();
3) 读取数据
PS1:
一个重要的问题,TCP 客户端和服务端传输数据的时候,
bufferedWriter一定要加回车符,即newLine(),以及flush()。
因为BufferedReader只有读到回车符,才会返回数据。
PS2:TCP传输的时候一定要考虑结束标记,通常关闭客户端输出流,shutdownOutput()
在发送数据前先发送一个时间戳给服务端
3. 具体小实例
1) UDP:
import java.net.*;
import java.io.*;
import java.lang.*;
class Send implements Runnable
{
public void run()
{
try
{
DatagramSocket ds = new DatagramSocket(10001);
byte[] data;
String s = null;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while((s=br.readLine())!=null)
{
if(s.equals("88"))
break;
data = s.getBytes();
DatagramPacket dp =
new DatagramPacket(data,data.length,
InetAddress.getByName("192.168.1.102"),10000);
ds.send(dp);
}
ds.close();
}
catch (Exception e)
{
}
}
}
class Rec implements Runnable
{
public void run()
{
try
{
DatagramSocket ds = new DatagramSocket(10000);
byte[] data = new byte[1024];
while(true)
{
DatagramPacket dp = new DatagramPacket(data,data.length);
ds.receive(dp);
String s = new String(data,0,dp.getLength());
System.out.println(dp.getAddress().getHostName()+"..."
+dp.getAddress().getHostAddress()+":"+s);
if(s.equals("88"))
break;
}
ds.close();
}
catch (Exception e)
{
}
}
}
class UDPDemo
{
public static void main(String[] args)
{
new Thread(new Send()).start();
new Thread(new Rec()).start();
}
}
2)TCP:
import java.io.*;
import java.net.*;
class TCPClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.102",20000);
String line = null;
String readLine = null;
BufferedReader brin = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bwout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader brinput = new BufferedReader(new InputStreamReader(s.getInputStream()));
while((line=brin.readLine())!=null)
{
if(line.equals("88"))
break;
bwout.write(line);
bwout.newLine();
bwout.flush();
readLine=brinput.readLine();
System.out.println(readLine);
}
s.close();
brin.close();
}
}
class TCPServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(20000);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+"connected");
BufferedReader brin = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter brout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while((line=brin.readLine())!=null)
{
if(line.equals("88"))
break;
System.out.println(line);
brout.write(line.toUpperCase());
brout.newLine();
brout.flush();
}
s.close();
ss.close();
}
}