Socket ,套接字。一个socket 地址是有网络地址和端口号组成的通信标识符。
进程间通信操作需要一对socket .进程间通信通过在一个进程中的一个socket 与另一个进程中的另一个socket 进行数据传输完成。当一个消息执行发出后,这个消息在发送端的socket 中处于排队状态,直到下层的网络协议将这些消息发送出去。当消息到达接收端的socket 后,其也会处于排队状态,直到接收端的进程对这条消息进行了接收处理。
TCP和UDP通信
关于socket 编程有两种通信协议可进行选择。一种是数据报通信,另一种是流通信
数据报通信
即UDP(User Data Protocol 用户数据报协议)。UDP是一种无连接的协议,这意味着我们每次发送数据报时,需要同时发送本机的socket描述符和接收端的socket 描述符,因此,每次通信时都需要发送额外的数据
流通信
也叫做TCP(Transfer Control Protocol,传输控制协议)。和UDP 不同,TCP 是一种基于连接的协议。在使用流通信之前,必须在一对socket 之间建立连接。其中一个socket 作为服务器进行监听连接请求,另一个作为客户端进行连接请求。一旦两个socket建立好了连接,他们可以单向或双向进行数据传输。
下面以流通信进行代码示范
public class SocketTest {
@org.junit.Test
public void test() {
String host = "127.0.0.1";
int port = 8990;
//创建一个socket服务
ServerSocket serverSocket = null;
//创建一个socket 客户端
Socket socket = null;
try {
serverSocket = new ServerSocket(port);
socket = new Socket(host, port);
socket.setKeepAlive(true);
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
Writer writer = new OutputStreamWriter(socket.getOutputStream());
writer.write("socket 写入");
writer.flush();
writer.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
Socket acceptSocket = serverSocket.accept();
Reader reader = new InputStreamReader(acceptSocket.getInputStream());
char chars[] = new char[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = reader.read(chars)) != -1) {
sb.append(new String(chars, 0, len));
}
System.out.println(sb.toString());
// DataInputStream is = new DataInputStream(acceptSocket.getInputStream()) ;
// PrintStream os = new PrintStream(acceptSocket.getOutputStream());
//
//
// while(true){
// String line = is.readLine();
// os.println(line);
// }
reader.close();
acceptSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
http://www.importnew.com/20245.html
TCP 套接字的生命周期如下:
1)建立TCP连接
新的Socket 实例创建后就立即能用于发送和接收数据。也就是说当Socket 实例返回时,他已经连接到了一个远程终端,并通过协议的底层实现完成了TCP消息或握手信息的交换
2)客户端连接的建立
调用Socket 的构造函数时,底层实现将创建一个套接字实例,该实例的初始状态是关闭的。
TCP开放握手也称为3次握手。通常包括3条消息:一条从客户端到服务端的连接请求,一条从服务器端到客户端的确认消息,以及另一条从客户端到服务器端的确认消息。
对于客户端来讲,一旦它接收到服务端发来的确认消息,就立即认为连接已经建立。
3)服务器端连接的建立
服务器端可以调用ServerSocket的accept方法返回客户端发送的消息。程序会在accept()方法处阻塞,以等待客户端的连接请求,一旦取得连接,便要为每个客户端的连接建立一个Socket实例来实现数据通信
4)关闭TCP 连接
close() 或shutdownOutput()方法
可能有两种情况:
1,先有一个应用程序调用close()方法或shutdownOutput(),并在另一端调用close 方法前关闭握手消息
2,两端同时调用close 方法,他们的关闭握手消息在网络上交叉传输
关于数据报通信
1)在UDP 程序中,创建DatagramPacket 实例时,如果没有指定远程主机地址和端口,则该实例用来接收数据,若指定了,用来发送数据
2)在receive()方法处阻塞,直到收到一个数据报文或等待超时,可以通过setSoTimeout()方法来指定receive()方法的最长阻塞时间
3)所有通信使用同一套接字,这点和TCP 服务器不同TCP服务器为每个成功返回的accept 创建一个新的套接字
4)DatagramSocket的每一次receive()调用最多只能接收调用一次send()方法所发送的数据,而且不同的receive()方法不会返回同一个send()方法所发送的数据