网络编程基本概念
1.网络程序:能够接受另外一台计算机发送过来的数据或者向另一台计算机发送数据的程序叫做网络程序。
2.IP:网络上唯一标识一台主句的编号。在网络是每台主机只有一个唯一的IP地址,IP地址是一个逻辑地址,因特网上的IP具有全球唯一性;IP以4个字节表示,一般用点分十进制格式表示。例如:192.168.1.1
3.mac地址:网卡,是物理地址,每个机器的mac地址都是不一样的,改不了,而IP地址是可以修改的。
4.端口号:采用一个16位数字表示,范围是0~65535,通常1024以下的端口不适用,留给预定义服务。例如:80端口访问网页。25端口邮件发送。(一台计算机运行多个网络程序时,一台计算机从网卡接受的数据应该交给本地哪个网络程序处理,这个由端口号来决定)。
5.协议:为进行网络中数据通信而建立的规则、标准或者是约定。常见协议有TCP和UDP协议。
如下图所示是两个计算机进行某一个网络程序数据通信的过程。
6.TCP协议:面向连接的可靠的传输协议。类似打电话
7.UDP协议:是无连接的不可靠的传输协议。类似写信
8.socket(套接字):是为了方便开发网络应用,美国伯克利大学在Unix上推出一种应用程序访问通信协议的才做系统调用socket。socket使程序员可以很方便的访问TCP/IP。
UDP
基于UDP的socket编程步骤
1.定义一个码头
即:定义一个DatagramSocket对象ds
2.定义用来接受或者发送数据的集装箱
即:定义一个DatagramPacket对象dp
3.在码头上用集装箱接受对方发送的数据(ds.receive(dp);)或者在码头上把集装箱中的数据发送给对方(ds.send(dp));
4.关闭码头(ds.close())
服务器程序如下:
import java.net.*;
import java.io.*;
public class TestUDPServer
{
public static void main(String[] args) throws Exception
{
//定义码头
DatagramSocket ds = new DatagramSocket(5678); // 5678表示该码头占用的是5678这个编号,因为一台计算机可以有多个码头接受多个数据,这些码头用不同编号表示,这个编号也叫做端口号
//定义可以用来接收数据的集装箱
byte buf[] = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
try
{
while(true)
{
//在码头上用集装箱接受对方发送过来的数据
ds.receive(dp); //注意:本语句执行完毕就以为这,dp数组将码头接受到的数据放到dp箱子里
//从箱子中取出对方发送过来的数据
ByteArrayInputStream bais = new ByteArrayInputStream(dp.getData());
DataInputStream dis = new DataInputStream(bais);
System.out.println(dis.readLong());
}
}
catch (Exception e)
{
e.printStackTrace();
ds.close(); // 关闭码头
}
}
}
客户端程序:
import java.net.*;
import java.io.*;
public class TestUDPClient
{
public static void main(String[] args) throws Exception
{
//定义码头
DatagramSocket ds = new DatagramSocket(5678);
//12行到19行
long n = 10000L;//12行
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(n); //把n变量所代表的10000L写入dos所依附的bao
byte buf[] = baos.toByteArray(); //DataOutputStream流中没有
DatagramPacket dp = new DatagramPacket(buf,buf.length,new InetSocketAddress("192.168.199.143",5678));
//在码头上把集装箱中的数据发送给对方
ds.send(dp);
ds.close(); // 关闭码头
}
}
TCP
基于TCP的socket编程
服务端程序:
import java.net.*;
import java.io.*;
public class TCPServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(6666); // 8行 6666是端口号,表示该服务器程序在监听6666端口是否有客户端程序的连接
//new出的ServerSocket对象ss并不会自动监听客户端有没有向6666端口发送请求,要想监听6666端口是否有客户端的请求,则必须得调用ss对象的accept方法
//若本程序只有8行代码,则本程序运行时将无任何输出结果并会立即终止
while(true)
{
Socket s = ss.accept(); // accept()功能:等待客户端的连接
//这里的s实际是连接到客户端的s,服务器端的s.
//accept()是阻塞式方法,如果接受不到客户端的连接
System.out.println("一个连接已经建立!!!");
DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println(dis.readUTF());
dis.close();
s.close();
}
}
}
客户端程序:
import java.net.*;
import java.io.*;
public class TCPClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.199.143",6666); // 8行
//第一个参数是要连接到的主机IP,即表示要连接到那
//new Socket("192.168.1.1",6666)一旦构造对象成功
//如果这时IP为192.168.1.1的机器上正好有一个网络
//所谓连接成功是指着两个网络程序建立了一个通信
//记住:一旦new出了Socket对象,该对象就会自动
//因此我们在TCP编程的客户端是找不到请求连接的代码
OutputStream os = s.getOutputStream();//16行 一旦连接成功
//程序如果能执行到16行说明已连接成功,因为,或者服务器端虽然已经打开但是却没有监听客户端请求
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("同志们好");
dos.flush();
dos.close();
s.close();
}
}