初识socket简单创简单你server连接
基于tcp协议,建立稳定性连接的点对点通信。
实时、快速。安全性高、占用系统资源多。效率低
“请求-响应” 模式
客户端:在网络通讯中,第一次主动发起通讯的程序被称作客户端(client)程序
服务器:第一次通讯中等待连接的程序被称作服务器端(Server)程序
Socket:发送TCP消息
ServerSocket:创建服务器
套接字:是一种进程间的数据交换机制。这些进程既可以在同一机器上,也可以在网络连接的不通机器上
换句话说,套接字起到通信端点的作用。单个套接字是一个端点,而一对套接字则构成了一个双向通信信道
使非关联进程可以在本地或通过网络进行数据交换。一旦建立套接字连接,数据即可在相同或不通的系统中双向或单项发送,
直到其中一个端点关闭连接。
简单的Socket连接
server端:
public class Server{
public static void main(String[] args) throws IOException {
//1.创建 服务器制定端口
ServerSocket server = new ServerSocket(8888);
//2.接收客户端连接,阻塞式(表示没有客户端接入不会向下运行)
Socket socket = server.accept();
System.out.println("一个客户端进行了连接!");
}
}
client端:
public class Client {
//使用下面方式进行简单的连接:一直端口和ip进行连接
Socket client = new Socket("localhost", 8888);
}
先运行server中的main方法,然后运行client重的main方法,
在服务器端的控制台会打印:
一个客户端进行连接字样
使用DataInputStream和DataOutputStream流传输
客户端代码:
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.创建客户端,必须制定服务器+端口
Socket client = new Socket("localhost", 8888);
//2.接收数据
/*
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
String echo = br.readLine();//阻塞式方法 分行接收不会报错(解决方法:在server的传输字符串可以+ /r/n 或者在 write方法后面+newLine())
System.out.println(echo);
*/
DataInputStream da = new DataInputStream(client.getInputStream());
String re = da.readUTF();
System.out.println(re);
}
}
服务器端:
使用while死循环使server一直在与你系那个状体,(后续会改进,使用多线程进行开发)
public class Server{
public static void main(String[] args) throws IOException {
//1.创建 服务器制定端口
ServerSocket server = new ServerSocket(8888);
//2.接收客户端连接,阻塞式
while(true){
//死循环,一个accrpt一个客户端
Socket socket = server.accept();
System.out.println("一个客户端进行了连接!");
//3.发送数据
String msg = "欢迎使用";
//输出流 输出流和输入流是成对的
/*
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream()));
bw.write(msg);
bw.newLine();
bw.flush();
*/
DataOutputStream da = new DataOutputStream(socket.getOutputStream());
da.writeUTF(msg);
da.flush();
}
}
}
这其中的BufferedWriter 和BufferedReader 不推荐使用
运行方式,首先运行Server中的main方法,控制台会显示
之后运行client的main方法
表示接收到server传过来的数据
使用InputStream和OutputStream传输
和使用DataInputStream和DataOutputStream类似,
server端:
public class Server {
public static void main(String[] args) throws IOException {
//1.创建 服务器制定端口
ServerSocket server = new ServerSocket(8888);
//2.接收客户端连接,阻塞式
while(true){
//死循环,一个accrpt一个客户端
Socket socket = server.accept();
System.out.println("一个客户端进行了连接!");
//3.发送数据
String msg = "欢迎使用";
OutputStream os = socket.getOutputStream();
try {
byte[] by = LoUtils.hexStr2Bytes(LoUtils.str2HexStr(msg)); //传入shuju
String len = "0000" + by.length;
len = len.substring(len.length() - 4);
byte[] lenlen = len.getBytes("UTF-8");
byte[] true_body = LoUtils.assemble(lenlen,by);
os.write(true_body);
os.flush();
} catch (Exception e) {
}
}
}
}
client端:
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.创建客户端,必须制定服务器+端口
Socket client = new Socket("localhost", 8888);
//2.接收数据
byte[] lenbtyte = new byte[4];
input.read(lenbtyte, 0, 4);
int resplen = Integer.parseInt(new String(lenbtyte, "UTF-8"));
byte[] pack = new byte[resplen];
input.read(pack, 0, resplen);
String res = new String(pack, "UTF-8");
System.out.println(res);
}
}
运行成功后和上面的结果相同,就表示正确了。
工具类LoUtils:
public class LoUtils {
//2进制到16进制Str转换
public static String str2HexStr(String str) throws Exception {
char[] chars = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder("");
byte[] bs = str.getBytes("UTF-8");
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append(chars[bit]);
bit = bs[i] & 0x0f;
sb.append(chars[bit]);
}
return sb.toString();
}
/**
* 十六进制字符串转换成bytes
*
* @param src
* @return
*/
public static byte[] hexStr2Bytes(String src) {
int m = 0, n = 0;
int l = src.length() / 2;
byte[] ret = new byte[l];
for (int i = 0; i < l; i++) {
m = i * 2 + 1;
n = m + 1;
ret[i] = uniteBytes(src.substring(i * 2, m), src.substring(m, n));
}
return ret;
}
//转换成 已只长度的 数组段
public static byte[] assemble(byte[]... b) throws Exception {
int length = 0;
for (byte[] bl : b) {
if (bl != null)
length += bl.length;
}
byte[] data = new byte[length];
int count = 0;
for (int i = 0; i < b.length; i++) {
if (b[i] != null) {
System.arraycopy(b[i], 0, data, count, b[i].length);
count += b[i].length;
}
}
return data;
}
}
本人相对比较习惯使用DataInputStream和DataOutputStream
传输比较简单容易理解。
Tips:亲测上述方法可用特此分享