——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
网络编程:
两台机器远程传数据:
1、找到对方IP;
2、数据要发送到对方指定的应用程序上。为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这个数字,就叫做端口(逻辑端口);
3、定义通信规则,这个通讯则称为协议。国际组织定义了通用协议TCP/IP。
网络通讯的要素包括以下几个:
1、IP地址:InetAddress
它的常用方法有:
getByName( host ) :给定主机名确定 IP 地址
getHostAddress( ):返回 IP 地址字符串
getLocalHost( ):返回本地主机
getAddress( ):返回此 InetAddress 对象的原始 IP 地址
等等。。
2、端口号:
用于标识进程的逻辑地址,不同进程的标识。
有效端口:0—65535,其中0—1024是系统使用或保留端口。
3、传输协议;
常见的协议有:UDP 和 TCP
UDP
将数据及源和目的封装成数据包中,不需要建立连接。
每个数据报的大小在限制在64k内。
因无连接,是不可靠协议。
不需要建立连接,速度快。
如:QQ聊天、视频会议等用的都是UDP传输协议。
TCP
建立连接,形成传输数据的通道。
在连接中进行大数据量传输。
通过三次握手完成连接,是可靠协议。
必须建立连接,效率会稍低。
应用案例:如迅雷下载。
UDP例子如下:
import java.net.*;
public class IPDemo
{
public static void main(String[] args) throws Exception {
//获取指定IP地址对象
InetAddress ip=InetAddress.getByName("19.125.141.210");
System.out.println(ip.getHostAddress());
System.out.println(ip.getHostName());
System.out.println("----------------");
//获取新浪的地址。
ip = InetAddress.getByName("www.sina.com");
System.out.println(ip.getHostAddress());
System.out.println(ip.getHostName());
}
}
Socket:
Socket就是为网络服务提供的一种机制。
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。
UDP的发送端和接收端例子如下:
import java.net.*;
public class UDPSendDemo
{
public static void main(String[] args) throws Exception {
System.out.println("发送端启动......");
//DatagramSocket 即能发送,又能接收
DatagramSocket ds = new DatagramSocket();
String str = "aaaaa";
byte[] buf = str.getBytes();
//DatagramPacket 是数据报包,可以接收,也可以发送(参数不同)
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("19.125.141.210"),10000);
ds.send(dp);
ds.close();
}
}
import java.net.*;
public class UDPReceDemo
{
public static void main(String[] args) throws Exception {
System.out.println("接收端启动......");
DatagramSocket ds = new DatagramSocket(10000);
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(),0,dp.getLength());
System.out.println(ip + ":" + port + ":" + text);
ds.close();
}
}
注意:UDP传输一般要先开启接收端,再开启发送端发送,否则有可能数据会丢失,因为发送端只管发送数据。
发送端:
import java.net.*;
import java.io.*;
public class UDPSend
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds=new DatagramSocket();
//接收键盘输入的数据
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null){
byte[] buf=line.getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName(
"19.125.141.210"),10000);
ds.send(dp);
if(line.equals("886")) //如果接收到的数据为“886”,则退出循环,程序结束。
break;
}
br.close();
ds.close();
}
}
接收端:
import java.net.*;
public class UDPReceive
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds=new DatagramSocket(10000);
while(true)
{
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
ds.receive(dp);
String text=new String(dp.getData(),0,dp.getLength()); //把接收到的字节转成字符串
System.out.println(dp.getAddress().getHostAddress()+"..."+dp.getPort()+"..."+text);
if(text.equals("886"))
break;
}
ds.close();
}
}
下面是一个类似于广播的例子,用到了多线程技术:
import java.net.*;
import java.io.*;
public class Send implements Runnable
{
private DatagramSocket ds;
public Send(DatagramSocket ds)
{
this.ds=ds;
}
public void run()
{
try{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null)
{
byte[] buf=line.getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,
InetAddress.getByName("19.125.141.255"),10001); //地址
19.125.141.255是一个广播地址,凡是19.125.141.XX 这个网段的用户都能接收到消息
ds.send(dp);
if(line.equals("886"))
break;
}
ds.close();
}
catch(Exception e)
{
e.printStackTrace();
; }
}
}
import java.net.*;
public class Receive implements Runnable
{
private DatagramSocket ds;
public Receive(DatagramSocket ds)
{
this.ds=ds;
}
public void run()
{
try
{
while(true)
{
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
ds.receive(dp);
String text=new String(dp.getData(),0,dp.getLength());
System.out.println(dp.getAddress().getHostAddress()+"..."+
dp.getPort()+"..."+text);
if(text.equals("886"))
System.out.println(dp.getAddress().getHostAddress()+"退出聊天室");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
import java.net.*;
public class UDPDemo
{
public static void main(String[] args) throws Exception
{
DatagramSocket send=new DatagramSocket();
DatagramSocket receive=new DatagramSocket(10001);
Send s=new Send(send);
Receive r=new Receive(receive);
new Thread(r).start();
new Thread(s).start();
}
}
TCP协议例子:
客户端
import java.net.*;
import java.io.*;
public class ClientDemo
{
public static void main(String[] args) throws Exception {
Socket s= new Socket("19.125.141.210",10002);
OutputStream out = s.getOutputStream(); //该方法返回Socket的输出流
out.write("bbbbbbbb".getBytes());
s.close();
}
}
服务端:
import java.net.*;
import java.io.*;
public class ServerDemo{
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10002);
Socket s = ss.accept(); //服务器接收一个要访问的客户端Socket
String ip = s.getInetAddress().getHostAddress();
InputStream in = s.getInputStream(); //该方法返回Socket的输入流
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(ip + ":" + text);
s.close();
ss.close();
}
}
TCP交互,即有反馈信息,例子如下:
客户端:
import java.net.*;
import java.io.*;
public class ClientDemo
{
public static void main(String[] args) throws Exception {
Socket socket = new Socket("19.125.141.210",10002);
OutputStream out = socket.getOutputStream();
out.write("我的消息".getBytes());
InputStream in = socket.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(text);
socket.close();
}
}
服务端:
import java.net.*;
import java.io.*;
public class ServerDemo{
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10002);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(ip + ":" + text);
OutputStream out = s.getOutputStream();
out.write("收到".getBytes());
s.close();
ss.close();
}
}
可以通过TCP进行文件上传功能:
服务端:
import java.net.*;
import java.io.*;
public class Server
{
public static void main(String[] args) throws Exception
{
ServerSocket ss=new ServerSocket(10000);
Socket s=ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+"....connect");
BufferedReader br=new BufferedReader(new InputStreamReader
(s.getInputStream()));
BufferedWriter bw=new BufferedWriter(new FileWriter("f:\\server.txt"));
String line=null;
while((line=br.readLine())!=null)
{
bw.write(line);
bw.newLine();
}
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功");
ss.close();
br.close();
bw.close();
}
}
客户端:
import java.net.*;
import java.io.*;
public class Client
{
public static void main(String[] args) throws Exception
{
Socket s=new Socket("192.168.1.100",10000);
BufferedReader br=new BufferedReader(new FileReader("f:\\client.txt"));
PrintWriter pw=new PrintWriter(s.getOutputStream(),true); //参数加true,表示
会自动刷新
String line=null;
while((line=br.readLine())!=null)
{
pw.println(line); //注意:只有在调用 println、printf 或 format 的其中一个方法才会自动刷新
}
s.shutdownOutput(); //这句话很重要,告诉服务器,客户端写完了
BufferedReader brIn=new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(brIn.readLine());
br.close();
brIn.close();
pw.close();
s.close();
}
}