- OSI模型与TCP/IP协议栈
- 端口
- TCP UDP
- Socket ServerScoket DatagramSocket
OSI参考模型
OSI(Open System Interconnect),即开放式系统互联。 一般都叫OSI参考模型,该体系结构标准定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层和应用层),针对攻城狮们,我们不需要过多的去关注物理层、数据链路层,
网络层:IP地址的寻址,查询互联网中某台服务器
传输层:(TCP/UDP)实现端到端的通信
会话层: 实现端到端的之间的交互信息
表示层: 端到端的之间的交互形式
应用层: :HTTP,HTTPS,FTP,TELNET,SSH,SMTP,POP3等。
-
TCP/IP协议栈
端口
端口有什么用呢?我们知道,一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区 分不同的服务的。
TCP/UDP
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠、基于字节流的传的输层通信协议,TCP为了保证报文传输的可靠[1] 就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
-
客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
-
服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入 SYN_RECV状态。
-
客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序
对比:UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同,TCP协议中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时,会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。与TCP不同,UDP协议并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据报的丢失,协议本身并不能做出任何检测或提示。因此,通常人们把UDP协议称为不可靠的传输协议。TCP在现实当中就像我们打电话先拨通在说话,UDP就像是发短信
- Socket ServerScoket DatagramSocket
TCP 套接字处理流程
UDP 套接字处理流程
--------参考资料------------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class ClientTcp
{
private static final String host = "localhost";
private static final int port = 1999;
public static void main(String[] args)
throws IOException
{
Socket scoketClient = null;
OutputStream writer = null;
BufferedReader buffer = null;
String readLine = null;
try
{
while (true)
{
scoketClient = new Socket(host, port);
writer = scoketClient.getOutputStream();
buffer = new BufferedReader(new InputStreamReader(scoketClient.getInputStream()));
int c;
while ((c = System.in.read()) != -1)
{
writer.write(c);
if (c == '\n')
{
writer.flush();
break;
}
}
System.out.println("Server:" + buffer.readLine());
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
scoketClient.close();
writer.close();
buffer.close();
}
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server
{
static final int port = 1999;
static final ExecutorService service = Executors.newFixedThreadPool(10);
public static void main(String[] args)
throws IOException
{
ServerSocket serverScoket = null;
try
{
serverScoket = new ServerSocket(port);
while (true)
{
Socket socket = serverScoket.accept();
System.out.println(socket);
service.submit(new Work(socket));
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
serverScoket.close();
}
}
}
class Work implements Runnable
{
Socket scoket;
BufferedReader reader = null;
BufferedWriter writer = null;
public Work(Socket scoket)
throws IOException
{
this.scoket = scoket;
this.reader = new BufferedReader(new InputStreamReader(scoket.getInputStream()));
this.writer = new BufferedWriter(new OutputStreamWriter(scoket.getOutputStream(), "UTF-8"));
}
@Override
public void run()
{
String readLine = null;
try
{
while ((readLine = reader.readLine()) != null)
{
System.out.println(readLine);
int c;
while ((c = System.in.read()) != -1)
{
writer.write(c);
if (c == '\n')
{
writer.flush();
break;
}
}
break;
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
scoket.close();
reader.close();
writer.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ClientUDP
{
public static void main(String[] args)
throws IOException
{
DatagramSocket client = null;
try
{
client = new DatagramSocket();
byte[] sendBytes = {'a', 'b', 'c'};
byte[] recvBytes = new byte[1024];
InetAddress ipAddress = InetAddress.getByName("localhost");
DatagramPacket sendPackage = new DatagramPacket(sendBytes, sendBytes.length, ipAddress, 1999);
client.send(sendPackage);
DatagramPacket recvPackage = new DatagramPacket(recvBytes, recvBytes.length);
client.receive(recvPackage);
System.out.println(new String(recvPackage.getData(), "GBK"));
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
client.close();
}
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ServerUDP
{
public static void main(String[] args)
throws IOException
{
DatagramSocket client = null;
byte[] sendBytes = {'h', 'e', 'l'};
byte[] recvBytes = new byte[1024];
try
{
client = new DatagramSocket(1999);
while (true)
{
System.out.println("服务监听。。。。。");
DatagramPacket revc = new DatagramPacket(recvBytes, recvBytes.length);
client.receive(revc);
System.out.println("Recv:" + new String(revc.getData()));
DatagramPacket send =
new DatagramPacket(sendBytes, sendBytes.length, revc.getAddress(), revc.getPort());
client.send(send);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
client.close();
}
}
}
《Java网路编程》
《百度百科》