huangzonggui 2019-12-09
1、socket原理
Socket实质上提供了进程通信的端点。进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。正如打电话之前,双方必须各自拥有一台电话机一样。
套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
1、服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
2、客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3、连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
2、基于java中的socket编程
客户端:
import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class client { public static void main(String args[]) throws Exception { // 连接本地主机,端口自设,与服务端一致即可 String host = "127.0.0.1"; int port = 23333; // 通过socket与服务端建立连接 Socket socket = new Socket(host, port); if(socket.isConnected()){ System.out.println("Connected!"); } // 将要发送的信息写入输出流 OutputStream output = socket.getOutputStream(); String sent = "hello"; socket.getOutputStream().write(sent.getBytes("UTF-8")); // 关闭客户端的输出流(单向,并未关闭socket) socket.shutdownOutput(); System.out.println("sent message to server: " + sent); // 读取从server返回的输入流 InputStream input = socket.getInputStream(); byte[] bytes = new byte[1024]; int len; StringBuilder get = new StringBuilder(); while ((len = input.read(bytes)) != -1) { get.append(new String(bytes, 0, len,"UTF-8")); } System.out.println("get message from server: " + get); // 关闭socket input.close(); output.close(); socket.close(); } }
服务器端:
import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class server { public static void main(String[] args) throws Exception { // 监听指定的端口,阻塞直至客户端连接此端口 int port = 23333; ServerSocket server = new ServerSocket(port); System.out.println("server is waiting..."); Socket socket = server.accept(); System.out.println("Connected!"); // 读取从客户端返回的输入流,至尾端时返回-1 InputStream input = socket.getInputStream(); byte[] bytes = new byte[1024]; int len; StringBuilder get = new StringBuilder(); while ((len = input.read(bytes)) != -1) { get.append(new String(bytes, 0, len, "UTF-8")); } System.out.println("get message from client: " + get); OutputStream output = socket.getOutputStream(); String sent = "Hi there"; output.write(sent.getBytes("UTF-8")); System.out.println("sent message to client: " + sent); // 关闭socket与服务器端 input.close(); output.close(); socket.close(); server.close(); } }
实验结果:
首先运行服务器
然后运行客户端
然后服务器端结果
3、程序思路
(1)建立一个服务器ServerSocket,并同时定义好ServerSocket的监听端口;
(2)ServerSocket 调用accept()方法,使之处于阻塞。
(3)创建一个客户机Socket,并设置好服务器的IP和端口。
(4)客户机发出连接请求,建立连接。
(5)分别取得服务器和客户端ServerSocket 和Socket的InputStream和OutputStream.
(6) 利用Socket和ServerSocket进行数据通信。
4、linux中的socket与windows中socket文件之间的区别。
socket作为套接字,能够对数据进行包装后进行发送,socket本质是一个文件。
Linux中是将socket文件视为普通文件,而在windows中将socket文件看成是一个网络连接来对待,因此需要调用专门针对 socket 而设计的数据传输函数。
在window操作系统中,使用native
标注的本地方法在编译时会生成一个动态链接库(.dll文件)为JAVA语言提供相应的本地服务。
int socket(itn domain, int type, int protocol); // 创建一个套接字 | |
int bind(int sockfd, const struct sockaddr *addr, socklen_t addelen);// 将套接字绑定到地址上 | |
int listen(int sockfd, int backlog); // 监听连接 | |
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);// 接收一个连接请求 |