网络编程
一、基础概念
-
概念
基于网络协议,实现网络程序开发,用于多台计算机互联网通信的网络编程模式,网络应用程序区别与普通程序,网络程序需要有网络环境才可以运行,常见的如QQ,迅雷…… -
通信模型
- OIS7曾模型(概念模型)
- TCP/IP通信模型(广泛使用)
- OIS7曾模型(概念模型)
-
IP地址协议
网络地址协议,用于标识计算机的位置,是计算机在网络环境中的身份标识 -
端口
同一台计算机,数据类型的通道,不同的应用通过绑定不同的端口来,来收发特定端口的数据范围0~65535
-
UPL统一资源定位符,用于定位网络中的一切“资源”,比如文件、服务等。
http://www/baidu.com/index.html
协议 + IP + 端口 + 资源名称
二、基于TCP Scoket编程
基本步骤
1.创建服务端套接字ServerSocket并指定端口
2.调用accept()监听
3.通过Scoket的输入输出流,读写客户端数据
1.创建客户端套接字Scoket 并指定连接的IP和端口
2.通过Scoket的传入输入输出流 读写客服端数据
实例:
//服务器端
public class ServerDemo {
public static void main(String[] args) {
perrConnection();
}
public static void perrConnection(){
try {
//1.创建服务器端,指定端口
ServerSocket server= new ServerSocket(9090);
System.out.println("等到客户端连接中");
while (true){
//等待连接,会阻塞线程,知道有客户端连接上,返沪连接的客户端,接触阻塞
Socket socket =server.accept();
System.out.println(socket.getInetAddress()+"连接…………");
//把链接上的客户端存入集合
friends.add(socket);
//单独为每个客户端开一个线程,处理通信问题
Thread th= new Thread(new ServerTask(socket));
th.start();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
class ServerTask implements Runnable{
//声明链接上来的客户端
private Socket client;
public ServerTask(Socket client) {
this.client = client;
}
//处理当前客户端与服务端通信
@Override
public void run() {
//接受客户端发来的消息
try {
//获得输入流
BufferedReader bbs = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line;
while ((line = bbs.readLine()) != null){
System.out.println(client.getInetAddress().getHostAddress()+": "+ line);
//转发
disPacher(line,ServerDemo.friends);
}
} catch (IOException e) {
System.out.println(client.getInetAddress()+"下线了");
ServerDemo.friends.remove();
}
}
public void disPacher(String msg,LinkedList<Socket> friebdss) throws IOException {
for (Socket socket : friebdss){
if (socket == client ){
continue;
}
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println(msg);
}
}
}
//客户端
public class ClientDemo {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1",9090);
Thread t1 = new Thread(new ClientTask(socket));
t1.start();
while (true){
System.out.print(socket.getLocalAddress()+": ");
String msg = sc.next();
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println(msg);
}
}
}
class ClientTask implements Runnable{
private Socket socket;
public ClientTask(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
//从socket中读取转发来的信息
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = br.readLine())!=null){
System.out.println(socket.getInetAddress().getHostName()+line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、TCP与UPD
-
tcp是一种面向连接的可靠传输协议,连接断开通过三次握手和四次挥手,传输数据两没限制。
三次握手:- 第一次握手:建立连接时,客户端发送syn包(seq = j)到服务器,并进入SYN_SENT状态,等待服务器确认
SYN:同序列编号:Synchronize Sequence Numbers
-
第二次握手:服务器收到syn包,必须确认客户的SYN(ack = j+1),同时自己也发送一个SYN包 (sep = k),即SYN+ACK包,此时服务器进入SYN_RECV状态。
-
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack = k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手
四次挥手:
- 第一次次挥手:客户端发送一个FIN=M,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。意思是说"我客户端没有数据要发给你了",但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。
- 第二次挥手:服务器端收到FIN后,先发送ack=M+1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。
- 第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
- 第四次挥手:客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手。
-
UDP
是一种无连接的传输协议,传输不可靠,可能丢包,只是尽最大努力送达,效率高,每个包限制64kb。