学习目的
一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。
在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。
而TCP层则提供面向应用的可靠(tcp)的或非可靠(UDP)的数据传输机制,
这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。
目前较为流行的网络编程模型是客户机/服务器(C/S)结构。
即通信双方一方作为服务器等待客户提出请求并予以响应。
客户则在需要服务时向服务器提 出申请。
服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,
就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也 能及时得到服务。(网络摘抄)
知识点
- 两种常见的网络协议的支持
- 端口(port)
- 统一资源定位符(URL)
- Socket
- Socket通信
解析
- 两种常见的网络协议的支持
TCP:TCP 是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。
TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。
通过TCP协议传输,得到的是一个顺序的无差错的数据流。
发送方和接收方的成对的两个socket之间必须建 立连接,
以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,
另一个socket可以要求进行连接,一旦这两个socket连接起来,
它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。
tcp/ip基础--ip地址与包的路由传递
ip地址(唯一识别某一电脑)
概述:每个internet上的主机和路由器都有一个ip地址,它包括网络号和主机号,所有ip地址都是32位的,ip地址按照国际标准的划分为a,b,c,d,e五种类型。UDP:UDP 是用户数据报协议的缩写,一个无连接的协议。提供了应用程序之间要发送的数据的数据包。
UDP是User Datagram Protocol的简称,是一种无连接的协议,
每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,
因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。比较:
UDP:
1.每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。
2.UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。
3.UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方
TCP:
1.面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中需要连接时间。
2.TCP传输数据大小限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大的数据。
3.TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。
端口(port)
在网络技术中,端口(Port)有好几种意思。集线器、交换机、路由器的端口指的是连接其他网络设备的接口,如RJ-45端口、Serial端口等。我们这里所指的端口不是指物理意义上的端口,而是特指TCP/IP协议中的端口,是逻辑意义上的端口。
如果把IP地址比作一间房子,端口就是出入这间房子的门。真正的房子只有几个门,但是一个IP地址的端口可以有65536(即:256256)个之多!端口是通过端口号来标记的,端口号只有整数,范围是从0到65535(256256-1)。
端口号:唯一标识电脑上的某一个进程(程序)80统一资源定位符(URL)
统一资源定位符(URL,英语Uniform Resource Locator的缩写)也被称为网页地址,是因特网上标准的资源的地址。它最初是由蒂姆·伯纳斯-李发明用来作为万维网的地址的。现在它已经被万维网联盟编制为因特网标准RFC1738了。
Internet上的每一个网页都具有一个唯一的名称标识,通常称之为URL地址,这种地址可以是本地磁盘,也可以是局域网上的某一台计算机,更多的是Internet上的站点,简单地说,URL就是Web地址,俗称“网址”,是用于完整地描述Internet上网页和其他资源的地址的一种标识方法。
url--组成
http://www.sina.com:8080/index.html
1、协议;2、ip地址(32位);3、端口号(16位)0-65535;4、资源名称。Socket
4.1 所谓socket 通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。
以J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
4.2 重要的Socket API
java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。
- Accept方法用于产生”阻塞”,直到接受到一个连接,并且返回一个客户端的Socket对象实例。”阻塞”是一个术语,它使程序运行暂时”停留”在这个地方,直到一个会话产生,然后程序继续;通常”阻塞”是由循环产生的。
- getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。
- getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用
- Socket通信实例
5.1 基础模式
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
public static void main(String[] args) throws Exception {
// 监听指定的端口
int port = 55533;
ServerSocket server = new ServerSocket(port);
// server将一直等待连接的到来
System.out.println("server将一直等待连接的到来");
Socket socket = server.accept();
// 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = inputStream.read(bytes)) != -1) {
//注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
sb.append(new String(bytes, 0, len,"UTF-8"));
}
System.out.println("get message from client: " + sb);
inputStream.close();
socket.close();
server.close();
}
}
import java.io.OutputStream;
import java.net.Socket;
public class SocketClient {
public static void main(String args[]) throws Exception {
// 要连接的服务端IP地址和端口
String host = "127.0.0.1";
int port = 55533;
// 与服务端建立连接
Socket socket = new Socket(host, port);
// 建立连接后获得输出流
OutputStream outputStream = socket.getOutputStream();
String message="你好 yiwangzhibujian";
socket.getOutputStream().write(message.getBytes("UTF-8"));
outputStream.close();
socket.close();
}
}
5.2 双向通信,发送消息并接受消息
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class myclass {
}
class Client{
public static void main(String[] args) throws IOException {
Socket socket=new Socket("10.129.14.97",8888);
new Thread(new ClientThread(socket)).start();
BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
PrintStream ps=new PrintStream(socket.getOutputStream());
String line=null;
while ((line=keyin.readLine())!=null){
ps.println(line);
}
}
}
class ClientThread implements Runnable{
private Socket socket;
public ClientThread(Socket socket){
this.socket=socket;
}
@Override
public void run() {
BufferedReader br=null;
try {
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line=null;
while ((line=br.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络错误");
System.exit(-1);
}finally {
try {
if (br!=null) {
br.close();
}
if (socket!=null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class Server{
public static void main(String[] args) throws IOException {
ServerSocket serverSocket=new ServerSocket(8888);
Socket socket=serverSocket.accept();
new ServerThread(socket).start();
BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
PrintStream ps=new PrintStream(socket.getOutputStream());
String line=null;
while ((line=keyin.readLine())!=null){
ps.println(line);
}
}
}
class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
System.out.println("网络错误");
System.exit(-1);
}
}
}
5.3 多向通信,多人发送消息并接受消息
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class MyClass {
}
class Server{
public static ArrayList<Socket> sockets=new ArrayList<>();
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(8888);
while (true){
Socket socket=ss.accept();
sockets.add(socket);
new ServerThread(socket).start();
}
}
}
class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
for (Socket s:Server.sockets) {
PrintStream ps=new PrintStream(s.getOutputStream());
ps.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
System.out.println("网络错误");
System.exit(-1);
}
}
}
}
class Client{
public static void main(String[] args) throws IOException {
Socket socket=new Socket("10.129.14.97",8888);
new Thread(new ClientThread(socket)).start();
BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
PrintStream ps=new PrintStream(socket.getOutputStream());
String line=null;
while ((line=keyin.readLine())!=null){
ps.println(line);
}
}
}
class ClientThread implements Runnable{
private Socket socket;
public ClientThread(Socket socket){
this.socket=socket;
}
@Override
public void run() {
BufferedReader br=null;
try {
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line=null;
while ((line=br.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络错误");
System.exit(-1);
}finally {
try {
if (br!=null) {
br.close();
}
if (socket!=null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
感悟
今天学习的是网络编程,主要是对它基础的了解以及socket的学习,虽然写了几个Damon,但是他的基本用法都是一样的,所以主要是对它的基本了解。然后再经过上面几个代码的练习便可基本掌握。在以往的编程中是很枯燥的,但是网络的学习,让我发现了乐趣,它让我体验不太一样的聊天和群聊,它让我知道了QQ和微信的消息是如何运作的。所以继续加油吧!