一个程序员如果开发网络程序,就会使用到SOCKET网络协议,很多的编程语言都含有这个网络协议,这里使用java来说说这个应用广泛的网络协议。
一、Socket综述
1、Socket网络连接是一种有状态的网络协议,它建立在TCP协议之上,在程序设计中被广泛的应用。
2、Socket的连接:使用首先需要在服务器端打开一个端口并监听,客户端通过服务器的IP和端口就可以进行连接,它是一对一的连接,而且必需先打开服务器,再打开客户端。
服务器可以使用以下代码在主机下打开一个网络端口:
//服务器等待连接
private ServerSocket server=null;
//用户连接服务器
private Socket user=null;
//发送流
private PrintWriter pw=null;
//输入流
private InputStreamReader isr=null;
//读取流
private BufferedReader br=null;
//通过一个端口port建立服务器并等待连接
public void LocalServer(int port){
try {
server = new ServerSocket(port);
user= server.accept();
isr = new InputStreamReader(user.getInputStream());
br = new BufferedReader(isr);
pw = new PrintWriter(user.getOutputStream(), true);
} catch (IOException e) {
e.printStackTrace();
}
}
客户端连接可以使用以下代码:
//通过ip地址和端口port连接服务器
public void ConnectServer(String ip,int port){
try {
user = new Socket(ip, 12138);
pw = new PrintWriter(user.getOutputStream(), true);
isr = new InputStreamReader(user.getInputStream());// IO读取接收内容
br = new BufferedReader(isr);
} catch (Exception e) {
e.printStackTrace();
}
}
Socket注意:在java中服务器端执行到accept()时会一直监听端口是否被连接,就像睡眠一样不再往下执行,当使用一个线程完成连接网络和其它任务时往往会直接锁在等待被连接上,所以使用Socket时要注意是否会在等待连接上被锁死直到它被连接上,可以使用多线程来解决这个问题,单独使用一个线程来开始一个Socket连接就不会发生卡死的现象。连接一个ip的Socket就比较简单了,Socket(ip, port)函数首先访问ip主机,没有访问到就直接报错失败,如果访问到,查看port端口是否有Socket在等待连接,如果没有报错连接失败,如果有就连接成功,接下来就可以在服务器与客户端之间传递数据,另外需要声明的是java中Socket是一对一的连接,当一个端口被连接上后就不能在连接第二个用户。
3、Socket的数据发送与接收:
Socket的数据发送使用PrintWriter.println(String message);使用这个函数即可发送message字符串数据。Socket的数据接收是一直接收的一旦有消息传递到,它会马上收到,它的使用如以下:br.readLine当消息到达时就会往下执行。while循环就是一直接收消息。
while(true){
String info=br.readLine();
}
4、Socket的断开:Socket的断开可以使用close函数,它由一方请求断开连接,另一方同意断开连接前通知自己同意断开连接并断开连接,请求断开连接方接收到同意断开指令后断开连接,断开时含有多个对象,所以使用以下函数逐层释放资源。
//关闭连接
public void close(){
try{
if(br!=null)
br.close();
if(pw!=null)
pw.close();
if(isr!=null)
isr.close();
if(user!=null)
user.close();
if(server!=null)
server.close();
}catch(Exception e){
e.printStackTrace();
}
}
二、java Socket使用例子
封装Socket协议建立服务器,连接服务器,关闭连接方法。
package Network;
/*
* @vamesary
* 13/5/2017
* Socket网络协议
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ConnectSocket {
//服务器等待连接
private ServerSocket server=null;
//用户连接服务器
private Socket user=null;
//发送流
private PrintWriter pw=null;
//输入流
private InputStreamReader isr=null;
//读取流
private BufferedReader br=null;
//构造函数
public ConnectSocket(){
}
//通过一个端口port建立服务器并等待连接
public void LocalServer(int port){
try {
server = new ServerSocket(port);
user= server.accept();
isr = new InputStreamReader(user.getInputStream());
br = new BufferedReader(isr);
pw = new PrintWriter(user.getOutputStream(), true);
} catch (IOException e) {
e.printStackTrace();
}
}
//通过ip地址和端口port连接服务器
public void ConnectServer(String ip,int port){
try {
user = new Socket(ip, 12138);
pw = new PrintWriter(user.getOutputStream(), true);
isr = new InputStreamReader(user.getInputStream());// IO读取接收内容
br = new BufferedReader(isr);
} catch (Exception e) {
e.printStackTrace();
}
}
public PrintWriter getPw() {
return pw;
}
public void setPw(PrintWriter pw) {
this.pw = pw;
}
public void setBr(BufferedReader br) {
this.br = br;
}
public BufferedReader getBr() {
return br;
}
//关闭连接
public void close(){
try{
if(br!=null)
br.close();
if(pw!=null)
pw.close();
if(isr!=null)
isr.close();
if(user!=null)
user.close();
if(server!=null)
server.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
测试:建立服务器
package Network;
/*
* @vamesary
* 13/5/2017
* 测试Socket建立服务器
*/
import java.io.BufferedReader;
import java.io.PrintWriter;
public class TestSocketServer {
private static PrintWriter pw=null;
private static BufferedReader br=null;
public static void main(String[] args) {
ConnectSocket cs=new ConnectSocket();
cs.LocalServer(12138);
System.out.println("connect success");
pw=cs.getPw();
br=cs.getBr();
try{
while(true){//循环读取消息
//读取一行消息
String info=br.readLine();
if(info.equals("close")){
pw.println("yes");
System.out.println("Server close!");
cs.close();
break;
}else{
System.out.println("Server receive: "+info);
pw.println("i am server");
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
测试:连接服务器
package Network;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
/*
* @vamesary
* 13/5/2017
* 测试Socket连接服务器
*/
public class TestSocketUser {
private static PrintWriter pw=null;
private static BufferedReader br=null;
public static void main(String[] args) {
ConnectSocket cs=new ConnectSocket();
//127.0.0.1默认为本地主机ip
cs.ConnectServer("127.0.0.1", 12138);;
pw=cs.getPw();
br=cs.getBr();
//发送一条消息
pw.println("Hello i am user");
try {
while(true){//循环读取消息
//读取一行消息
String info=br.readLine();
if(info.equals("yes")){
cs.close();
System.out.println("User close!");
break;
}else{
System.out.println("User receive: "+info);
pw.println("close");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
connect success
Server receive: Hello i am user
Server close!
客户端输出:
User receive: i am server
User close!