前言
数据在Internet中是以有限大小的包形式传输的,这些包称为数据报(datagram)。每个数据报包含一个首部(header)和一个有效载荷(payload)。首部包含所去往的地址和端口、包来自的地址和端口以及用于保证可靠传输的各种其他管理信息。有效载荷包含数据本身。但是,由于数据报长度有限,通常必须将数据分解多个包,在目的地再重新组合。也有可能一个包或多个包在传输中丢失或遭到破坏,需要重传;或者包乱序到达,需要重新排序。记录这些事情(将数据分解为包、生成首部、解析入站包的首部、记住哪些包是否收到等等)是很繁重的工作,需要大量的复杂代码。
socket让程序员可以将网络连接视为另一种可以读取字节的流。socket对程序员掩盖了网络的低层细节,如纠错、包大小、包重传、网络地址等等。
java的socket
java的socket默认使用TCP协议,socket类可以用于客户端和服务端,建立一个服务端通过ServerSocket类来实现。建立了连接之后,客户端和服务端都可以从socket获取输入流和输出流,使用这两个流彼此发送数据。连接是全双工的。两端都可以同时发送和接收数据。
1.Socket类主要方法
getOutputStream();//返回一个输出流,将程序的数据写入socket的另一端
getInputStream();//返回一个输入流,将socket的数据读入程序
Socket类的getOutputStream()方式往socket写入数据,一定要flush(),否则会让另一端socket在一直等待。
Socket类的getInputStream()方式读取数据的操作是阻塞的,如果从输入流读取不到数据,程序会一直阻塞不动,直到另一端往socket里写入数据。
2.ServerSocket类主要方法
accept(); accept()方法监听服务端口的入站连接,accept()会一直阻塞,直到客户端尝试连接,这里accept()会返回一个连接客户端和服务端的一个Socket对象。
服务端程序:
public class SerSocket {
public static void main(String[] args){
int port = 8000;
String ip = "127.0.0.1";
if(args != null && args.length > 0){
port = Integer.valueOf(args[0]);
if(args.length > 1){
ip = args[1];
}
}
ServerSocket server = null;
try {
server = new ServerSocket(port);
System.out.println("server is on host:" + server.getInetAddress().getHostAddress()
+ ", port:" + server.getLocalPort());
while(true){
Socket socket = server.accept();
InputStreamReader reader = null;
OutputStreamWriter writer = null;
try{
System.out.println("some request get in");
int len;
char[] b = new char[1024];
String temp;
StringBuilder sb = new StringBuilder();
reader = new InputStreamReader(socket.getInputStream());
while((len = reader.read(b, 0, 1024)) != -1){
temp = new String(b, 0, len);
sb.append(b, 0, len);
//读取输入流里数据的结束符,则跳出循环
if(temp.indexOf("\r\n\r\n") != -1) break;
}
System.out.println("request from client:" + sb.toString());
writer = new OutputStreamWriter(socket.getOutputStream());
writer.write("server has accepted the request.\r\n\r\n");
writer.flush();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(reader != null) reader.close();
if(writer != null) writer.close();
socket.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(server != null)
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端程序:
public class ClientSocket {
public static void main(String[] args){
OutputStreamWriter writer = null;
InputStreamReader reader = null;
Socket socket = null;
try {
socket = new Socket("192.168.20.103", 8000);
System.out.println("there is a server on host:" + socket.getInetAddress() + ", port:" + socket.getPort());
OutputStream outputStream = socket.getOutputStream();
writer = new OutputStreamWriter(outputStream);
writer.write("I am parameter.\r\n\r\n");
writer.flush();
reader = new InputStreamReader(socket.getInputStream());
int len;
char[] b = new char[1024];
String temp;
StringBuilder sb = new StringBuilder();
while((len = reader.read(b, 0, 1024)) != -1){
temp = new String(b, 0, len);
sb.append(b, 0, len);
//读取输入流里数据的结束符,则跳出循环
if(temp.indexOf("\r\n\r\n") != -1) break;
}
System.out.println("response from server:" + sb.toString());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(writer != null)writer.close();
if(reader != null)reader.close();
if(socket != null)socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}参考:
java socket 编程http://haohaoxuexi.iteye.com/blog/1979837
本文详细介绍Java Socket编程的基本概念及其实现方法。包括数据报的结构、Socket类的主要方法、ServerSocket类的使用等,并提供了客户端和服务端的示例代码。
1346

被折叠的 条评论
为什么被折叠?



