@(java 技术笔记)
Socket基本用法及实现长链接
Socket是java中基于Tcp/Ip协议实现的一个网络通信技术,用于进行java中的网络通信,实现长链接等。
注意:
1.java socket是阻塞式的,所以构建socket进行读写操作的时候,需要构建线程进行。
2.如果是在移动端使用,只有一个或者两个的连接的时候可以使用原生的socket。 但如果是服务端处理大量的客户端连接的时候就需要使用 第3方的网络框架。 比如mina。
下面是使用原生socket实现服务端和客户端的长链接,
客户端代码:
public class SocketClient {
BufferedWriter writer=null;
BufferedReader reader=null;
public static void main(String[] args) {
//在java程序的入口,启动Sokcet程序
SocketClient client=new SocketClient();
client.start();
}
public void start(){
BufferedReader inputReader=null;
Socket socket=null;
try {
//构建一个inputReader对象,读取控制台的输入数据
inputReader=new BufferedReader(new InputStreamReader(System.in));
//构建Socket实例,连接到服务器端
//172.16.1.148 为 服务端ip 9898为服务端端口号
socket=new Socket("172.16.1.148", 9898);
// writer 对象用于向服务端写数据,reader对象用于向服务端读数据
writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
reader =new BufferedReader(new InputStreamReader(socket.getInputStream()));
startServerReplyListener(reader);
String inputContent;
//读取控制台的输入,并向服务端写数据
while(!(inputContent=inputReader.readLine()).equals("bye")){
System.out.print(inputContent+"\n");
writer.write(inputContent+"\n");
writer.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
writer.close();
reader.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 构建一个线程,去实时从reader中读取服务端的数据
* @param reader
*/
public void startServerReplyListener(final BufferedReader reader){
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
String response;
while((response=reader.readLine())!=null){
System.out.print("server say="+response+"\n");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
服务端代码:
public class SocketServer {
public static void main(String[] args) {
//在java程序的入口,启动服务端Sokcet程序
SocketServer server=new SocketServer();
server.startServer();
}
public void startServer(){
ServerSocket serverSocket=null;
Socket socket=null;
try {
//构建服务端socket实例
serverSocket=new ServerSocket(9898);
System.out.print("server start..."+"\n");
//当socket调用了accept程序,程序就会阻塞,直到有客户端连入。 所以在有客户端连入后,就把socket对象传入线程中,进行数据读写。 然后继续阻塞
//这样就保证每一个客户端对象,对应一个线程
while(true){
socket=serverSocket.accept();
managerConnection(socket);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
socket.close();
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 启动一个线程去对应没一个客户端,去进行数据读写
* @param socket
*/
public void managerConnection(final Socket socket){
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
BufferedWriter writer=null;
BufferedReader reader=null;
try {
System.out.print("client connect.."+socket.hashCode()+"\n");
// writer 对象用于向客户端写数据,reader对象用于向客户端读数据
reader =new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String receivedMsg;
while((receivedMsg=reader.readLine())!=null){
System.out.print(socket.hashCode()+"client say="+receivedMsg+"\n");
writer.write("server reply="+receivedMsg+"\n");
writer.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
reader.close();
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
}