如今的大多数网络通信都是选择使用基于TCP/IP的协议进行,其中封装的比较好的当属socket了,下面就socket的使用进行详细的描述:
一、Socket的工作模式
在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户/服务器(C/S)模式,即客户向服务器发出服务请求,服务器接收到请求后,提供相应的服务。主要工作模式可以描述如下:
服务器端:(首先服务器要先启动,服务器根据请求提供相应服务)
(1)打开一通信通道并告知本地主机,它愿意在某一公认地址上的某端口接收客户请求;
(2)等待客户请求到达该端口;
(3)接收到客户端的服务请求时,处理该请求并发送应答信号。当多任务的服务器接收到并发服务请求,会激活一新进程来处理这个客户请求。新进程处理此客户请求,并不需要对其它请求作出应答。服务完成后,关闭此新进程与客户的通信链路,并终止。
(4)返回第(2)步,等待另一客户请求。
(5)关闭服务器
客户端:
(1)打开一通信通道,并连接到服务器所在主机的特定端口;
(2)向服务器发服务请求报文,等待并接收应答;继续提出请求
(3)请求结束后关闭通信通道并终止。
二、工作原理
注:图片来源于网络百度百科。
(1)建立连接(三次握手)
客户端调用connect时,触发了连接请求,向服务器发送数据包,然后connect进入阻塞状态;服务器监听到连接请求调用accept函数接收请求向客户端发送确认数据包,然后accept进入阻塞状态;客户端收到服务器的确认数据包之后connect返回,并对数据包进行确认;服务器收到客户端的数据包时accept返回,通过三次握手建立连接。
(2)进行通信
服务器根据客户端的请求进行相应的应答。
(3)关闭连接(四次握手)
某个应用进程首先调用close主动关闭连接,这时TCP发送一个结束信号;服务器接收信号之后,执行被动关闭,
对这个信号进行确认。服务器发送一个确认信号给客户端,接收到文件结束符的应用进程调用close关闭它的socket,
最后向服务器发送一个确认信号。
三、一个具体的实例实现服务器和客户端的通信
服务器:
package connection;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
* User: dsy
* Date: 17-3-28
* Time: 上午9:44
* To change this template use File | Settings | File Templates.
*/
public class Server {
public static void main(String args[]) throws IOException {
int port = 5678;
//定义一个ServerSocket监听在端口5678上
ServerSocket server = new ServerSocket(port);
while (true) {
//server尝试接收其他Socket的连接请求(阻塞式的)
Socket socket = server.accept();
//接收到一个Socket就建立一个新线程来处理
new Thread(new Task(socket)).start();
}
}
/**
* 用来处理Socket请求的
*/
static class Task implements Runnable {
private Socket socket;
public Task(Socket socket) {
this.socket = socket;
}
public void run() {
try {
handleSocket();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 跟客户端Socket进行通信
*/
private void handleSocket() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String temp;
int index;
while ((temp=br.readLine()) != null) {
if ((index = temp.indexOf("end")) != -1) {//遇到end时就结束接收
sb.append(temp.substring(0, index));
break;
}
sb.append(temp);
}
System.out.println("receive from client: " + sb);
//输入发送信息
System.out.println(" send info:");
Writer writer = new OutputStreamWriter(socket.getOutputStream());
Scanner in = new Scanner(System.in);
String s = in.nextLine();
writer.write(s);
writer.write("end\n");
writer.flush();
writer.close();
br.close();
socket.close();
}
}
}
客户端:
package connection;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
* User: dsy
* Date: 17-3-28
* Time: 上午9:52
* To change this template use File | Settings | File Templates.
*/
public class Client {
public static void main(String args[]) throws Exception {
String host = "localhost"; //要连接的服务器IP地址
int port = 5678; //要连接的服务器端口号
//与服务器建立连接
Socket client = new Socket(host, port);
//往服务端写数据
System.out.println("Send info:");
Writer writer = new OutputStreamWriter(client.getOutputStream());
Scanner in = new Scanner(System.in);
String s = in.nextLine();
writer.write(s);
writer.write("end\n");
writer.flush();
//从服务器接受数据
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
StringBuffer sb = new StringBuffer();
String temp;
int index;
while ((temp=br.readLine()) != null) {
if ((index = temp.indexOf("end")) != -1) {
sb.append(temp.substring(0, index));
break;
}
sb.append(temp);
}
System.out.println("receive from server: " + sb);
writer.close();
br.close();
client.close();
}
}