java socket
来源:互联网 发布:注册淘宝企业店铺 编辑:程序博客网 时间:2024/05/06 23:17
SOCKET 解决问题 : 客户端 到 服务端 进行通信(TCP/IP 协议)
客户端 : java.net.Socket client = new Socket("127.0.0.1",80) ; 创建一个链接 IP 127.0.0.1 ,端口号80 的请求链接(底层已经调用connect() )。
服务端 : java.net.ServeSocket serve = new ServeSocket(80) ; 创建一个监听80端口的本地服务( 已经调用blind() )。
客户端与服务端有了 ,那么问题来了: 她们是如何建立连接进行通信(传输数据)的呢 ?
首先对于TCP/IP 协议,大家知道可靠连接是有3次握手的(客户端请求连接允许,服务器端发送允许链接,客户端发送链接请求),相对应的:
1、服务端已经做好客户端请求链接允许的准备:java.net.Socket socket = serve.accept() , serve会一直处于阻塞状态,直到请求来到。 (可简单启动main方法,debug 看程序加载到这行后还往下走么?)
2、客户端请求链接允许 :client.connect() , 如上面讲的,一般初始化的时候就已经connect(),所以不需要我们自己再调用。
3、服务端回复允许链接 : serve.accept()接收到消息,线程继续下走,client端也开始往下走,表示socket已经联通。
4、链接成功,那么通信 : 大家注意步骤一中标红处,serve.accept()返回的是连接的Socket,也就是客户端的socket,这样客户端就可以和服务端进行通信了 。socket有写入写出流进行消息通信 : Socket.getInputStream() 与 Socket.getOutputStream()。客户端和服务端都能使用该Socket的输入输出。
PS : 大家看到网上的例子程序经常会问 new BufferReader(new InputStreamReader(Socket.getInputStream)).readLine()方法为什么可以在客户端有数据的时候才执行 ,因为 BufferReader.readLine()本身是一个阻塞函数,只有在遇到了换行符或者对应流的结束F 才会结束阻塞。
客户端代码 :
package socketTest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* 客户端用来向Socket的Stream中写入数据
* 第一个采用一次连接一次输入的例子
*
* @author xubo
*
*/
public class SimpleSocketClient {
public static void main(String args[]) {
PrintWriter os = null;
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 4700);// 向本机的4700端口发出客户请求
BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); // 由系统标准输入设备构造BufferedReader对象
os = new PrintWriter(socket.getOutputStream()); // 由Socket对象得到输出流,并构造PrintWriter对象
String readline;
readline = sin.readLine(); // 从系统标准输入读入一字符串
while (!readline.equals("bye")) { // 若从标准输入读入的字符串为 "bye"则停止循环
os.println(URLEncoder.encode(readline, "UTF-8")); // 将从系统标准输入读入的字符串输出到Server
os.flush(); // 刷新输出流,使Server马上收到该字符串
System.out.println("Client:" + URLDecoder.decode(readline, "UTF-8"));
// 从Server读入一字符串,并打印到标准输出上
readline = sin.readLine(); // 从系统标准输入读入一字符串
} // 继续循环
os.close(); // 关闭Socket输出流
socket.close(); // 关闭Socket
} catch (Exception e) {
System.out.println("Error" + e);// 出错,则打印出错信息
}
}
}
===================================================================================
服务端代码 :
package socketTest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;
/**
* 不适用多线程,简单IO流 Socket通信
* 输出客户端接收到的数据
*
* @author xubo
*/
public class SimpleSocketServe {
public static void main(String args[]) {
try {
ServerSocket server = null;
try {
server = new ServerSocket();
server.bind(new InetSocketAddress(4700)); // 创建一个ServerSocket在端口4700监听客户请求
} catch (Exception e) {
System.out.println("can not listen to:" + e); // 出错,打印出错信息
}
Socket socket = null;
BufferedReader is = null;
try {
while (true) { // 循环等待
socket = server.accept(); // 使用accept()阻塞等待客户请求,有客户求到来则产生一个Socket对象,并继续执行
System.out.println("来了个客户端");
is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String ab = null;
while ((ab = is.readLine()) != null) { // 持续读取客户端输入的数据,直到客户端关闭流
System.out.println("从客户端读取数据:" + URLDecoder.decode(ab, "UTF-8"));
}
System.out.println("传输数据结束,等待下一个");
if (is != null) {
is.close();
}
if (socket != null) {
socket.close();
}
}
} catch (Exception e) {
System.out.println("Error." + e); // 出错,打印出错信息
} finally {
if (is != null) {
is.close();
}
if (socket != null) {
socket.close(); // 关闭Socket
server.close(); // 关闭ServerSocket
}
}
} catch (Exception e) {
System.out.println("Error:" + e);// 出错,打印出错信息
}
}
}
- java socket (-) 简单socket
- Java Socket
- java-socket
- java socket
- Java Socket
- JAVA Socket
- Java Socket
- socket(java)
- Java Socket
- Java socket
- java socket
- java socket
- Socket(java)
- Java socket
- Java Socket
- java socket
- Java Socket
- java socket
- 管理员重命名错误修改
- 使用 Google Guava 美化你的 Java 代码
- TCP、UDP、HTTP、Socket的区别
- 多线程/多进程的使用场景-Android
- java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区
- java socket
- 机器学习(二) - 一个最简单的线性分类模拟人脑神经工作
- 他们是有组织有预谋的
- ServletContextListener使用详解
- java/oracle日期处理
- 【bzoj1857】 Scoi2010—传送带
- Linux命令行与shell编程笔记-13处理用户输入
- HashMap、HashTable
- 进入组策略编辑器