网络编程
1.计算机网络
将分布在不同区域不同地方的多台计算机和网络设备通过线程连接起来组成一套大型系统,来实现计算机之间的信息传递和资源共享的设备.
2.网络编程
编写一个程序来实现计算机之间的信息传递和资源共享.
- 网络编程实现技术:IO流+多线程+网络编程
3.网络编程三要素:
- 1:IP:是计算机在网络中唯一标识.在同一个网络不能有相同IP,在不同的网络中可以有相同的IP.
本机回环地址:127.0.0.1,指代本机.
查看IP:cmd->ipconfig
ping ip:cmd->ping ip地址 - 2:端口:是网络中应用软件的唯一标识.端口范围065535,但是01024之间的端口被系统软件占用了.
- 3:协议:网络通信之间规则叫协议.
4.OSI七层模型和TCP/IP四层模型
5.InetAddress
此类表示Internet协议(IP)地址。
public static void main(String[] args) throws UnknownHostException {
//获得本机IP对象
InetAddress ia=InetAddress.getLocalHost();
//InetAddress ia=InetAddress.getByName("127.0.0.1");
System.out.println("本地主机名:"+ia.getHostName());
System.out.println("ip地址:"+ia.getHostAddress());
System.out.println("百度服务ip:");
//获得百度在深圳服务器的IP
InetAddress[] ips=InetAddress.getAllByName("www.baidu.com");
for (InetAddress i : ips) {
System.out.println(i.getHostAddress());
}
}
6.TCP网络编程:用的TCP协议.
- TCP协议
是一种安全的,面向链接的网络层协议.优点:安全性高(因TCP的客户端与服务器端要经过三次握手才能建立连接,连接后才能互发消息).缺点:效率低.
- Socket
客户端套接字(也称为“套接字”)。 套接字是两台机器之间通讯的信使.
-
ServerSocket
服务器套接字.监听客户端的套接字对象.
6.1:客户端发送消息,服务端接收消息
public static void main(String[] args) throws Exception {
//创建服务器端Socket
ServerSocket ss=new ServerSocket(6666);
System.out.println("客户端与服务器正在连接中...");
//监听客户端
Socket socket1=ss.accept();
System.out.println("客户端与服务器连接成功!");
//创建网络输入流
InputStream is=socket1.getInputStream();
/*读取客户端消息*/
//准备一个数组
byte[] b=new byte[100];
int len=is.read(b);
//将接收的客户端的消息转换为字符串
String word=new String(b, 0, len);
System.out.println("服务器接收客户端的消息为:"+word);
}
public static void main(String[] args) throws Exception {
//创建Socket对象
Socket socket1=new Socket("127.0.0.1", 6666);
//创建网络输出流
OutputStream is=socket1.getOutputStream();
//向服务发送消息
String word="Hello 服务器";
is.write(word.getBytes());
System.out.println("客户端向服务器发送消息为:"+word);
//关对象
socket1.close();
}
6.2:客户端发送消息,服务端回复消息,完成一次聊天
public static void main(String[] args) throws Exception {
//创建服务器端Socket
ServerSocket ss=new ServerSocket(7777);
System.out.println("客户端与服务器正在连接中...");
//监听客户端
Socket socket1=ss.accept();//表示客户端与服务器的三次握手
System.out.println("客户端与服务器连接成功!");
//创建网络流
InputStream is=socket1.getInputStream();
OutputStream os=socket1.getOutputStream();
/*读取客户端消息*/
//准备一个数组
byte[] b=new byte[100];
int len=is.read(b);
//将接收的客户端的消息转换为字符串
String word=new String(b, 0, len);
System.out.println("服务器接收客户端的消息为:"+word);
/*回复消息给客户端*/
String reword="收到,谢谢";
os.write(reword.getBytes());
System.out.println("服务器回复客户端的消息为:"+reword);
//关闭对象
ss.close();
}
public static void main(String[] args) throws Exception {
//创建Socket对象
Socket socket1=new Socket("127.0.0.1", 7777);
//创建网络流
OutputStream os=socket1.getOutputStream();
InputStream is=socket1.getInputStream();
//向服务发送消息
String word="Hello 服务器";
os.write(word.getBytes());
System.out.println("客户端向服务器发送消息为:"+word);
//接收服务器的消息
//准备一个数组
byte[] b2=new byte[100];
int len=is.read(b2);
//将接收的消息转换为字符串输出
System.out.println("客户端接收服务器的消息为:"+new String(b2, 0, len));
//关对象
socket1.close();
}
6.3:客户端与服务器端一对一循环聊天
public static void main(String[] args) throws Exception {
//创建服务器端socket
ServerSocket ss=new ServerSocket(8888);
System.out.println("客户端与服务器正在连接中...");
Socket socket2=ss.accept();
System.out.println("客户端与服务器连接成功!");
//创建网络流
BufferedWriter w=new BufferedWriter(new OutputStreamWriter(socket2.getOutputStream()));
BufferedReader r=new BufferedReader(new InputStreamReader(socket2.getInputStream()));
Scanner input=new Scanner(System.in);
while (true) {
/*服务器接收客户端消息*/
String word3=r.readLine();
System.out.println("服务器接收客户端消息为:"+word3);
/*服务器回复客户端的消息*/
System.out.println("服务器发消息给客户端为:");
String word4=input.nextLine();
//向服务发消息
w.write(word4);
//换行
w.newLine();
//刷新
w.flush();
if ("886".equals(word3)||"886".equals(word4)) {
break;
}
}
}
public static void main(String[] args) throws Exception {
//创建socket对象
Socket socket2=new Socket("127.0.0.1", 8888);
//创建网络流
BufferedWriter w=new BufferedWriter(new OutputStreamWriter(socket2.getOutputStream()));
BufferedReader r=new BufferedReader(new InputStreamReader(socket2.getInputStream()));
Scanner input=new Scanner(System.in);
while (true) {
/*客户端向服务器发送消息*/
System.out.println("客户端向服务器发消息为:");
String word1=input.nextLine();
//向服务发消息
w.write(word1);
//换行
w.newLine();
//刷新
w.flush();
/*客户端接收服务器消息*/
String word2=r.readLine();
System.out.println("客户端接收服务器消息为:"+word2);
if ("886".equals(word1)||"886".equals(word2)) {
break;
}
}
}
6.4:用TCP实现文件上传
public static void main(String[] args) throws Exception {
//创建socket对象
Socket socket1=new Socket("127.0.0.1",8888);
//创建本地读取流
InputStream is=new FileInputStream("C:\\Users\\masol\\Desktop\\image\\b.jpg");
//创建网络输出流
OutputStream os=socket1.getOutputStream();
//准备一个数组
byte[] b=new byte[1024];
//边读取本地磁盘上文件,边写入到服务器端
int len;
while ((len=is.read(b))!=-1) {
//每读取一次就写入一次
os.write(b,0,len);
os.flush();
}
System.out.println("客户端上传结束!");
//关对象
socket1.close();
}
public static void main(String[] args) throws Exception {
//创建服务端Socket
ServerSocket ss=new ServerSocket(8888);
System.out.println("客户端与服务器正在连接中...");
Socket socket1=ss.accept();
System.out.println("客户端与服务器连接成功");
//创建网络输入流
InputStream is=socket1.getInputStream();
//创建本地输出流
OutputStream os=new FileOutputStream("aa"+File.separator+"圆圆.jpg");
//准备一个数组
byte[] b=new byte[1024];
//边读取本地磁盘上文件,边写入到服务器端
int len;
while ((len=is.read(b))!=-1) {
//每读取一次就写入一次
os.write(b,0,len);
os.flush();
}
System.out.println("上传成功!");
}
7.UDP编程:用udp协议.
- udp协议:是一种不安全,无需建立连接的传输效率高的协议.UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内.udp没有服务器端,都是客户端.
- DatagramSocket:此类表示用于发送和接收数据报数据包的套接字。(两个网络传消息的信使) .
- DatagramPacket:该类表示数据报包。
7.1:(扩展)客户端1发送的接收一次客户端2的消息
public static void main(String[] args) throws Exception {
//创建socket对象,参数是当前这个客户端的端口号
DatagramSocket socket1=new DatagramSocket(1111);
/*客户端1发送消息给客户端2*/
//准备要发送的消息
byte[] b="恭喜你中了好声音第一等奖".getBytes();
//将要发送的消息打成数据发送包,第一个参数要发送的数据,第二个数据的长度,第三个是接收方IP对象,第四个是接收方的端口号
DatagramPacket packet1=new DatagramPacket(b,b.length, InetAddress.getByName("127.0.0.1"),2222);
//用socket发送数据包
socket1.send(packet1);
System.out.println(socket1.getLocalPort()+"发送给"+packet1.getPort()+"的消息为:"+new String(b));
/*客户端1接收客户端2回复的消息*/
//准备一个数组
byte[] b2=new byte[1024];
//构造一个接收包
DatagramPacket packet2=new DatagramPacket(b2,b2.length);
//用socket接收数据包
socket1.receive(packet2);
//获得接收的数据
String recieveMess=new String(packet2.getData(),0,packet2.getLength());
System.out.println(socket1.getLocalPort()+"接收"+packet2.getPort()+"消息为:"+recieveMess);
//关对象
socket1.close();
}
public static void main(String[] args) throws Exception {
//创建socket对象,参数是当前客户端的端口号
DatagramSocket socket2=new DatagramSocket(2222);
/*客户端2接收客户端1的消息*/
//准备一个数组
byte[] b=new byte[1024];
//构造一个数据接收包
DatagramPacket packet3=new DatagramPacket(b,b.length);
//用socket接收数据
socket2.receive(packet3);
//获得接收的数据
String recieveMess=new String(packet3.getData(),0,packet3.getLength());
System.out.println(socket2.getLocalPort()+"接收"+packet3.getPort()+"消息为:"+recieveMess);
/*客户端2回复客户端1的消息*/
//准备要回复(发送)的消息
byte[] sendMess="到哪里去领奖?".getBytes();
//将消息封装数据发送包
DatagramPacket packet4=new DatagramPacket(sendMess,sendMess.length, InetAddress.getByName("127.0.0.1"),1111);
//用socket将消息发送给客户端1
socket2.send(packet4);
System.out.println(socket2.getLocalPort()+"回复"+packet4.getPort()+"消息为:"+new String(sendMess));
//关流
socket2.close();
}
7.2:(扩展)客户端1发送的接收一次客户端2的消息
/**
*发送消息的线程
*/
public class SendThread extends Thread {
//声明发送方的socket对象
DatagramSocket socket1;
//声明接收方ip对象
InetAddress ip2;
//声明接收方端口
int port2;
/**
* 通过构造方法将发送方的socket,接收方ip对象,接收方端口
*
* @param socket1,
* @param ip2
* @param port2
*/
public SendThread(DatagramSocket socket1, InetAddress ip2, int port2) {
this.socket1 = socket1;
this.ip2 = ip2;
this.port2 = port2;
}
@Override
public void run() {
Scanner input = new Scanner(System.in);
try {
while (true) {
//准备要发送的消息
byte[] b = input.next().getBytes();
//将要发送的消息打成数据发送包,第一个参数要发送的数据,第二个数据的长度,第三个是接收方IP对象,第四个是接收方的端口号
DatagramPacket packet1 = new DatagramPacket(b, b.length, ip2, port2);
//用socket发送数据包
socket1.send(packet1);
System.out.println(socket1.getLocalPort() + "发送给" + packet1.getPort() + "的消息为:" + new String(b));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
*接收线程
*/
public class RecieveThread extends Thread{
//声明接收方的socket
DatagramSocket socket2;
/**
*用构造方法传入接收方的socket
*@param socket2
*@return
*/
public RecieveThread(DatagramSocket socket2) {
this.socket2 = socket2;
}
@Override
public void run() {
try {
while (true) {
//准备一个数组
byte[] b2 = new byte[1024];
//构造一个接收包
DatagramPacket packet2 = new DatagramPacket(b2, b2.length);
//用socket接收数据包
socket2.receive(packet2);
//获得接收的数据
String recieveMess = new String(packet2.getData(), 0, packet2.getLength());
System.out.println(socket2.getLocalPort() + "接收" + packet2.getPort() + "消息为:" + recieveMess);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
//创建socket对象,参数是当前这个客户端的端口号
DatagramSocket socket1=new DatagramSocket(1111);
//创建发送消息的线程和接收消息的线程
SendThread s=new SendThread(socket1, InetAddress.getLocalHost(),2222);
RecieveThread r=new RecieveThread(socket1);
//启动线程
r.start();
s.start();
}
public static void main(String[] args) throws Exception {
//创建socket对象,参数是当前客户端的端口号
DatagramSocket socket2=new DatagramSocket(2222);
//创建发送消息的线程和接收消息的线程
SendThread s=new SendThread(socket2, InetAddress.getLocalHost(),1111);
RecieveThread r=new RecieveThread(socket2);
//启动线程
r.start();
s.start();
}
个人笔记,思路,仅供参考