Socket网络通讯基础
怎么区分客户端与服务器端?
谁发起的请求,谁就为客户端,谁接受请求谁为服务端。
一、Socket入门
Socket就是为网络服务提供的一种机制
通讯的两端都有Socket
网络通讯其实就是Socket间通讯IO传输。
二、网络模型
应用层:
传输层:
网络层:
链路层:
任何计算机语言通讯,底层都使用socket技术。
Socket计数遵循一个规范:二进制+IP+端口号
Socket分为非常核心的两个:TCP UDP
三、UDP&TCP
1、udp:面向无连接--不会建立连接、数据传输64k 是不可靠协议
2、tcp:面向连接协议、三次握手、以字节流传输,UPD效率比TCP高,
tcp协议比udp靠谱
使用udp实现传输数据
先写服务器端。
案例:
package com.leeue.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/**
*
* @classDesc: 功能描述:(使用udp 来传输数据)
* @author:<a href="leeue@foxmail.com">李月</a>
* @Version:v1.0
* @createTime:2018年7月27日 上午11:14:46
*/
class UdpServer {
public static void main(String[] args) throws IOException {
System.out.println("udp服务器已经启动...");
DatagramSocket datagramSocket = new DatagramSocket(8080);
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
datagramSocket.receive(datagramPacket);
System.out.println("来源IP地址:"+datagramPacket.getAddress()+"端口号:"+datagramPacket.getPort());
String string = new String(datagramPacket.getData(),0,datagramPacket.getLength());
System.out.println(string);
datagramSocket.close();
}
}
public class UdpClient {
public static void main(String[] args) throws IOException {
System.out.println("upd客户端启动连接...");
DatagramSocket ds = new DatagramSocket();
String string="蚂蚁课堂";
byte[] strBytes = string.getBytes();
DatagramPacket dp = new DatagramPacket(strBytes, strBytes.length,InetAddress.getByName("127.0.0.1"),8080);
ds.send(dp);
ds.close();
}
}
四、TCP的三次握手
TCP协议采用三次握手成功之后,才开始进行数据传输。
在最后一次就会进行四次挥手,效率比UDP效率要慢。
在传输数据之前要经过三次握手确认,报文确认。
整个握手的时候是通过 TCP协议的。
四次分手也是类似这种。
TCP如果要关闭的话,两边都会进行关闭。
案例
五、TCP协议发送客户端与服务端
案例:
package com.leeue.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @classDesc: 功能描述:(TCP连接)
* @author:<a href="leeue@foxmail.com">李月</a>
* @Version:v1.0
* @createTime:2018年7月27日 下午2:48:59
*/
class tcpServer{
public static void main(String[] args) throws IOException {
System.out.println("tcp协议服务器启动了");
ServerSocket serverSocket = new ServerSocket(8080);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
String result = new String(bytes, 0, len);
System.out.println("服务器端接受客户端内容:"+result);
serverSocket.close();
}
}
public class TcpDemo {
public static void main(String[] args) throws IOException {
System.out.println("socket tcp 客户端启动...");
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("我是哈哈哈哈".getBytes());
socket.close();
}
}
Http协议底层就是使用TCP协议来进行传输的
怎么解决 tcp协议同时支持多个请求?
使用线程池,支持多个线程同时支持多个请求。 使用线程池来做伪异步的效果,
节约内存,
第一种方法:只能是一个线程在运行使用while循环来
package com.leeue.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @classDesc: 功能描述:(TCP连接)
* @author:<a href="leeue@foxmail.com">李月</a>
* @Version:v1.0
* @createTime:2018年7月27日 下午2:48:59
*/
class tcpServer{
public static void main(String[] args) throws IOException {
System.out.println("tcp协议服务器启动了");
ServerSocket serverSocket = new ServerSocket(8080);
try {
while(true) {
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
String result = new String(bytes, 0, len);
System.out.println("服务器端接受客户端内容:"+result);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
serverSocket.close();
}
}
}
public class TcpDemo {
public static void main(String[] args) throws IOException {
System.out.println("socket tcp 客户端启动...");
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("我是哈哈哈哈".getBytes());
socket.close();
}
}
第二种方法: 使用多线程优化的版本
package com.leeue.tcp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*
* @classDesc: 功能描述:(使用多线程支持多个连接访问)
* @author:<a href="leeue@foxmail.com">李月</a>
* @Version:v1.0
* @createTime:2018年7月27日 下午2:48:59
*/
class tcpServer {
public static void main(String[] args) throws IOException {
System.out.println("tcp协议服务器启动了");
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
ServerSocket serverSocket = new ServerSocket(8080);
try {
while (true) {
Socket accept = serverSocket.accept();
newCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
String result = new String(bytes, 0, len);
System.out.println("服务器端接受客户端内容:" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
serverSocket.close();
}
}
}
public class TcpDemo {
public static void main(String[] args) throws IOException {
System.out.println("socket tcp 客户端启动...");
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("我是哈哈哈哈".getBytes());
socket.close();
}
}