关于网络编程的相关知识
ip :是用来网络编程时,识别需要通信的电脑或主机端口号 :在获取主机ip 后,指定需要进行数据交流的APP 客户端 :用来向服务器发送数据或请求的电脑或主机服务器端 :用来接受客户端发送的数据或请求UDP编程的特点 :客户端与服务器端之间不需要确保已正确的连接,客户端只需要发送数据,而不保证服务器端能够正确的接收到客户端发送的数据。发送的数据都是以数据包的形式一个包一个包的发送,缺点就是不能够发送较大的数据TCP编程特点 :客户端与服务器端之间进行通信前必须保证已经建立正确的连接,数据之间的通信是通过管道(数据流)进行交互的,只要管道没有关闭,就可以一直进行数据的交流传递
一、 UDP网络编程
发送端(客户端): DatagramSocket ------> java.net.DatagramSocket ------> 创建socket DatagramPacket ------> java.net.DatagramPacket ------> 创建数据包 InetAddress ------> java.net.InetAddress ------> 封装ip 示例
import java. io. IOException ;
import java. net. DatagramPacket ;
import java. net. DatagramSocket ;
import java. net. InetAddress ;
import java. net. SocketException ;
import java. net. UnknownHostException ;
import java. util. Scanner ;
public class Udp_send_thread extends Thread {
private int port;
private String ip;
public Udp_send_thread ( int port, String ip) {
this . port = port;
this . ip = ip;
}
public void run ( ) {
DatagramSocket socket = null ;
try {
socket = new DatagramSocket ( ) ;
} catch ( SocketException e) {
System . out. println ( "创建socket失败" ) ;
}
InetAddress address = null ;
try {
address = InetAddress . getByName ( ip) ;
} catch ( UnknownHostException e) {
e. printStackTrace ( ) ;
}
Scanner input = new Scanner ( System . in) ;
while ( true ) {
String str = input. nextLine ( ) ;
DatagramPacket p = new DatagramPacket ( str. getBytes ( ) , str. length ( ) , address, port) ;
try {
socket. send ( p) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
if ( str. equals ( "end" ) ) {
break ;
}
}
if ( socket != null ) {
socket. close ( ) ;
}
}
}
接收端(服务器端): DatagramSocket ------> java.net.DatagramSocket ------> 创建socket DatagramPacket ------> java.net.DatagramPacket ------> 创建数据包 示例
import java. io. IOException ;
import java. net. DatagramPacket ;
import java. net. DatagramSocket ;
import java. net. SocketException ;
public class Udp_receive_thread extends Thread {
private int port;
public Udp_receive_thread ( int port) {
this . port = port;
}
public void run ( ) {
DatagramSocket socket = null ;
try {
socket = new DatagramSocket ( port) ;
} catch ( SocketException e) {
System . out. println ( "创建socket失败" ) ;
}
byte [ ] buf = new byte [ 1024 ] ;
while ( true ) {
DatagramPacket p = new DatagramPacket ( buf, buf. length) ;
try {
socket. receive ( p) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
String str = new String ( p. getData ( ) , 0 , p. getLength ( ) ) ;
System . out. println ( port + ":" + str) ;
if ( str. equals ( "end" ) )
break ;
}
if ( socket != null ) {
socket. close ( ) ;
}
}
}
接收端与发送端的不同 ① 发送端创建socket 不需要指定端口号,接收端需要指定 ② 发送端创建数据包需要指定端口号和ip 地址(用InetAddress 类进行封装),接收端只需要传递接收数据的缓存及长度 ③ 发送端发送数据用send ()函数,接收端接收数据用receive ()函数,接收到的数据用getData ()进行获取,长度用getLength ()获取 ④ 退出编程时,需要关闭socket 网络编程线程的调用
public class DCP_Main_Send1 {
public static void main ( String [ ] args) {
new Udp_send_thread ( 12345 , "127.0.0.1" ) . start ( ) ;
new Udp_receive_thread ( 12346 ) . start ( ) ;
}
}
public class DCP_Main_Send2 {
public static void main ( String [ ] args) {
new Udp_receive_thread ( 12345 ) . start ( ) ; ;
new Udp_send_thread ( 12346 , "127.0.0.1" ) . start ( ) ;
}
}
二、 TCP网络编程
发送端(客户端): Socket ------> java.net.Socket ------> 创建socket OutputStream ------> java.io.OutputStream ------> 创建输入流 示例
import java. io. IOException ;
import java. io. OutputStream ;
import java. net. Socket ;
import java. net. UnknownHostException ;
public class TcpSend {
public static void main ( String [ ] args) {
Socket socket = null ;
try {
socket = new Socket ( "127.0.0.1" , 12345 ) ;
OutputStream output = socket. getOutputStream ( ) ;
output. write ( "我是中国人,我很骄傲" . getBytes ( ) ) ;
} catch ( UnknownHostException e) {
e. printStackTrace ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
try {
if ( socket != null )
socket. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
}
接收端(服务器端): Socket ------> java.net.Socket ------> 创建socket ServerSocket ------> java.net.ServerSocket ------> 创建serverSocket InputStream ------> java.io.InputStream ------> 创建输出流 示例
import java. io. IOException ;
import java. io. InputStream ;
import java. net. ServerSocket ;
import java. net. Socket ;
public class TcpReceiva {
public static void main ( String [ ] args) {
ServerSocket serverSocket = null ;
Socket socket = null ;
try {
serverSocket = new ServerSocket ( 12345 ) ;
socket = serverSocket. accept ( ) ;
InputStream input = socket. getInputStream ( ) ;
byte [ ] buf = new byte [ 1024 ] ;
int length = input. read ( buf) ;
String str = new String ( buf, 0 , length) ;
System . out. println ( str) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
try {
if ( socket != null )
socket. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
try {
if ( serverSocket != null )
serverSocket. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
}
发送端与接收端的差异 ① 发送端使用Socket ,接收端使用ServerSocket ② 接收端创建ServerSocket 后需要通过accept ()函数获取客户端的socket ③ 发送端使用write ()函数发送数据,接收端使用read ()函数接收数据 ④ 发送端使用OutputStream 流,接收端使用InputStream 流 ⑤ 发送端创建Socket 需要传ip 和端口号,接收端创建ServerSocket 只需要传端口号