java中的网络编程

一 网络编程


1 1.1 概念:也叫socket编程,套接字编程;网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一识别的标识符套接字。
   1.2 原理:通信两端都有socket;
     网络通信其实就是socket通信;
     数据在两个socket间通过IO传输。
     1.3 三要素:
(1)ip:一个计算机的标识
127.0.0.1 本地回环地址 用来做一些本地测试
ping IP地址: 用来检测本机是否可以和指定的IP地址的计算机可以进行正常通讯
ipconfig: 用来查看IP地址
xxx.xxx.xxx.255 广播地址
(2)端口号:应用程序都会对应一个端口,用来进行通信。
物理端口 物理设备对应的端口, 网卡口
逻辑端口 用来标示我们的计算机上的进程 , 端口号的有效范围应该是 0-65535 ,
其中0-1024被系统占用或者保留
(3)协议:通信规则,分为UDP和TCP
2 UDP 
   2.1 特点:  
1.把数据打包
2.不需要建立连接,也称为面向无连接协议
3.数据需打包,数据大小有限制64k
4.无需建立连接,所以不可靠
5.速度快
   2.2 通信步骤:
1 发送端步骤:
(1)创建UDP发送数据的socket对象;(DatagramSocket)
(2)创建数据包,并给出相关数据参数;(DatagramPacket)
(3)通过socket对象发送数据;(send)
(4)释放资源;(close)
2 接收端步骤:
(1)创建UDP接收数据的socket对象;(DatagramSocket)
(2)创建接收数据包;(DatagramPacket)
(3)接收数据;(receive)
(4)解析数据包;(getData)
(5)释放资源;close

   2.3 案例
1 实现数据发送和接收
package udp_01;


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;


public class UdpClient {
public static void main(String[] args) throws Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket();


//创建数据包
byte[] buf = "hello".getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 4399; 
DatagramPacket dp = new DatagramPacket(buf, len, address, port);

//发送数据
ds.send(dp);

//释放资源
ds.close();
}
}


package udp_01;


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;


public class UdpServer {
public static void main(String[] args) throws Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket(4399);

//创建数据包
byte[] buf = new byte[1024];
int len  = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);

//接受数据
ds.receive(dp);

//解析数据
byte[] data = dp.getData();
int l = dp.getLength();
System.out.println(new String(data,0,l));

//释放资源
ds.close();
}
}
2 键盘录入数据实现数据的动态发送
package udp_02;


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;


public class UdpClient {
public static void main(String[] args) throws Exception {
//需求:键盘录入数据实现数据的动态发送

//创建socket对象
DatagramSocket ds = new DatagramSocket();

//创建键盘录入对象
Scanner sc = new Scanner(System.in);
String line;
while((line = sc.nextLine())!=null){
//创建数据包
byte[] buf = line.getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 4400;
DatagramPacket dp = new DatagramPacket(buf,len,address,port );

//发送数据
ds.send(dp);
}

//释放资源
ds.close();

}
}
package udp_02;


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;


public class UdpServer {
public static void main(String[] args) throws Exception {
//创建socket对象
DatagramSocket ds = new DatagramSocket(4400);


while(true){
//创建数据包
byte[] buf = new byte[1024];
int len = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);

//接受数据
ds.receive(dp);

//解析数据
byte[] data = dp.getData();
int l = dp.getLength();
System.out.println(new String(data,0,l));

}
}
}
3 多线程实现聊天室(相当于是将发送数据端和接收数据端合并)
package Udp_03;


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 UdpClient implements Runnable{
DatagramSocket ds ;

public UdpClient(DatagramSocket ds){
this.ds = ds;
}
public void run() {
try {
DatagramSocket ds = new DatagramSocket();

Scanner sc = new Scanner(System.in);
String line;
while((line=sc.nextLine())!=null){
byte[] buf = line.getBytes();
int len = buf.length;
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 5000;
DatagramPacket dp = new DatagramPacket(buf, len, address, port);

ds.send(dp);
}
ds.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}
}
package Udp_03;


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;


public class UdpServer implements Runnable{
DatagramSocket ds;
public UdpServer(DatagramSocket ds){
this.ds = ds;
}


@Override
public void run() {
try {
DatagramSocket ds = new DatagramSocket();

while(true){
byte[] buf = new byte[1024];
int len = buf.length;
DatagramPacket dp = new DatagramPacket(buf, len);

ds.receive(dp);

byte[] data = dp.getData();
int length = dp.getLength();
System.out.println(new String(data,0,length));
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}
}


package Udp_03;


import java.net.DatagramSocket;
import java.net.SocketException;


public class ChatRoom {
public static void main(String[] args) throws Exception {
new Thread(new UdpClient(new DatagramSocket())).start();
new Thread(new UdpServer(new DatagramSocket(5000))).start();
}
}


3 TCP
 3.1 特点:  
1.需要建立通道
2.无限制传送大量数据
3.面向连接
4.可靠
5.速度慢
   3.2 通信步骤:
1 发送端步骤:
(1)创建TCP发送端的socket对象;(Socket)
(2)获取输出流,并写数据(getOutputStream,write)
(3)释放资源;(close)
2 接收端步骤:
(1)创建TCP接收端的socket对象;(ServerSocket)
(2)监听客户端的链接;(accept)
(3)获取输入流并读取数据;(inputStream,read)
(4)输出;
(5)释放资源;(close)

   3.3 案例
1 用TCP协议写一个数据的发送和接收,接收端接收到数据之后给发送端一个反馈


package tcp_02;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;


public class TcpClient {
public static void main(String[] args) throws IOException, Exception {
Socket sk = new Socket("127.0.0.1",9876);

OutputStream os = sk.getOutputStream();

os.write("你喜欢的是谁?".getBytes());

InputStream is = sk.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));

sk.close();
}
}


package tcp_02;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(9876);

Socket sk = ss.accept();

InputStream is = sk.getInputStream();

byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));


OutputStream os = sk.getOutputStream();
os.write("刘诗诗".getBytes());

sk.close();
}
}
2 需求: 客户端键盘录入数据,服务器端接收数据在控制台输出
package tcp_03;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;


public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10086);

Socket sk = ss.accept();


while(true){
InputStream is = sk.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
}
}
}


package tcp_03;


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;


public class TcpClient {
public static void main(String[] args) throws Exception, IOException {
Socket sk = new Socket("127.0.0.1",10086);

Scanner sc = new Scanner(System.in);
String line;
while((line=sc.nextLine())!=null){
OutputStream os = sk.getOutputStream();
os.write(line.getBytes());
}

sk.close();
}
}
3 运用多线程实现文本文件的上传
分析:客户端:(1)读取文本文件中的数据
 (2)通过管道流将读取的数据发送到管道中(服务器端)
  服务器:(1)从管道流中读取数据
  (2)把读取的文件写入到文本文件中


package tcp_06;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;


public class TcpClient {
public static void main(String[] args) throws Exception, IOException {
Socket sk = new Socket("127.0.0.1",7878);

BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}

bw.close();
br.close();
sk.close();
}
}


package tcp_06;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;


public class ServerThread implements Runnable{
Socket sk;
public ServerThread(Socket sk){
this.sk = sk;
}
@Override
public void run() {

try {
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
BufferedWriter bw = new BufferedWriter(new FileWriter(new UUIDUtils().getFilename()));
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}

bw.close();
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


}


package tcp_06;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;


public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(7878);
while(true){
Socket sk = ss.accept();
new Thread(new ServerThread(sk)).start();

}
}
}


package tcp_06;
import java.util.UUID;
public class UUIDUtils {
public static String getFilename(){
String filename = UUID.randomUUID().toString();
return filename;
}
}


4 至此java中的网络编程部分结束,你只需要明确最重要一点:发送端就是客户端就是将数据发送到管道流中;接收端就是服务器端则是取出管道中的数据进行处理。
 注意:java.net.ConnectException: Connection refused: connect
  TCP协议是不能直接运行客户端的,必须先运行服务器。因为他是一种可靠的协议。




















































  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值