1.Socket网络编程之传递字符类型(图解与编码)
Java最初是作为网络编程语言出现的,它对网络的高度支持,使得客户端和服务器流畅的沟通变成现实。而在网络编程中,使用最多的就是Socket,每一个实用的网络程序都少不了它的参与。但Socket的底层机制却相当棘手,幸运的是,Java平台给我们一些虽然简单但是相当强大的类,可以使你更简单有效的使用Socket开发而无需了解底层机制。
请思考一下网络编程要解决的问题:而下面这些问题都可以用Socket来解决
- 如何建立两个节点(电脑)之间的网络连接?
- 如何向另外一个节点(电脑)发送信息?
- 如何从外部节点(电脑)接收一个请求并给予响应?
- 如何利用网络协议(TCP、UPD)?
已被广泛移植到了其他平台。
Socket实质上提供了进程通信的端点,网络上的两个程序通过一个双向的通讯链路实现数据的交换,这个双向链路的一端称为一个Socket。
ServerSocket类常用方法如下:
O了,讲了这么多理论原理的东西,我来讲讲编码方面的知识吧,上述理论只是过一个大概,并不详细,若对理论感兴趣的,可以上网上查询相关资料:
我写了一个简单的例子:一个Socket服务器,一个是调用此服务器端口的客户端。以下例子就是客户端向服务器的请求。代码如下:
-
package com.qhs.sockettest;
-
-
import java.io.BufferedReader;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.net.ServerSocket;
-
import java.net.Socket;
-
-
/**
-
* Socket服务器相关代码
-
* 编码完成后,要先运行服务器开启端口,然后再运行客户端。
-
*/
-
public class LoginServer {
-
public static void main(String args []){
-
try {
-
//1.建立一个服务器Socket绑定一个端口并开始监听
-
ServerSocket serverSocket = new ServerSocket( 8800);
-
-
//2.使用accept()方法阻塞等待监听,获得新的连接
-
Socket socket = serverSocket.accept();
-
//3.获得输入流
-
InputStream is = socket.getInputStream();
-
BufferedReader br = new BufferedReader( new InputStreamReader(is));
-
//4.获得用户输入信息
-
String info = null;
-
while(!((info=br.readLine())== null)){
-
System.out.println( "我是服务器,用户信息为:" + info);
-
}
-
//5.关闭资源
-
br.close();
-
is.close();
-
socket.close();
-
serverSocket.close();
-
-
} catch (IOException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
}
-
}
-
package com.qhs.sockettest;
-
-
import java.io.IOException;
-
import java.io.OutputStream;
-
import java.io.PrintWriter;
-
import java.net.Socket;
-
import java.net.UnknownHostException;
-
-
/**
-
* 客户端
-
*/
-
public class LoginClient {
-
-
public static void main(String args []){
-
-
try {
-
//1.建立客服端Socket连接,指定服务器的位置以及端口
-
Socket socket = new Socket( "localhost", 8800);
-
-
//2.得到Socket读写流
-
OutputStream os = socket.getOutputStream();
-
PrintWriter pw = new PrintWriter(os);
-
//3.利用流按照一定协议对Socket进行读/写操作
-
String info = "用户名:Jeff;用户密码:123456";
-
pw.write(info);
-
pw.flush();
-
//4.关闭资源
-
pw.close();
-
os.close();
-
socket.close();
-
-
} catch (UnknownHostException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
} catch (IOException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
-
}
-
}
测试进行时,请先运行服务器的代码,使得端口打开。然后再运行客户端去连接。最后在控制台输入的结果如图:
上面的例子就比如一个人打电话,另外一个人只是听,不说话,单向通信。所以运行后,后台只有客户端有服务器的信息
接下来,我们在上述代码中添加一些代码,使得服务器也有响应,等于双方相互通信的目的:
服务器代码:
-
package com.qhs.sockettest;
-
-
import java.io.BufferedReader;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.io.OutputStream;
-
import java.io.PrintWriter;
-
import java.net.ServerSocket;
-
import java.net.Socket;
-
-
/**
-
* Socket服务器相关代码
-
* 编码完成后,要先运行服务器开启端口,然后再运行客户端。
-
*/
-
public class LoginServer {
-
public static void main(String args []){
-
try {
-
//1.建立一个服务器Socket绑定一个端口并开始监听
-
ServerSocket serverSocket = new ServerSocket( 8800);
-
-
//2.使用accept()方法阻塞等待监听,获得新的连接
-
Socket socket = serverSocket.accept();
-
//3.获得输入流
-
InputStream is = socket.getInputStream();
-
BufferedReader br = new BufferedReader( new InputStreamReader(is));
-
-
//服务器的响应加进来的代码:获得输出流
-
OutputStream os = socket.getOutputStream();
-
PrintWriter pw = new PrintWriter(os);
-
-
//4.获得用户输入信息
-
String info = null;
-
while(!((info=br.readLine())== null)){
-
System.out.println( "我是服务器,用户信息为:" + info);
-
}
-
-
//添加代码:给客户一个响应
-
String reply = "服务的响应>>>>Welcome!";
-
pw.write(reply);
-
pw.flush();
-
//5.关闭资源
-
pw.close();
-
os.close();
-
br.close();
-
is.close();
-
socket.close();
-
serverSocket.close();
-
-
} catch (IOException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
}
-
}
客户端代码:
-
package com.qhs.sockettest;
-
-
import java.io.BufferedReader;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.io.OutputStream;
-
import java.io.PrintWriter;
-
import java.net.Socket;
-
import java.net.UnknownHostException;
-
-
/**
-
* 客户端
-
*/
-
public class LoginClient {
-
-
public static void main(String args []){
-
-
try {
-
//1.建立客服端Socket连接,指定服务器的位置以及端口
-
Socket socket = new Socket( "localhost", 8800);
-
-
//2.得到Socket读写流
-
OutputStream os = socket.getOutputStream();
-
PrintWriter pw = new PrintWriter(os);
-
-
//添加代码:输入流
-
InputStream is = socket.getInputStream();
-
BufferedReader br = new BufferedReader( new InputStreamReader(is));
-
-
//3.利用流按照一定协议对Socket进行读/写操作
-
String info = "用户名:Jeff;用户密码:123456";
-
pw.write(info);
-
pw.flush();
-
socket.shutdownOutput(); //关闭socket
-
//添加代码:接收服务器响应并打印显示
-
String reply = null;
-
while(!((reply=br.readLine())== null)){
-
System.out.println( "我是客户端,接收到服务器的响应为:" + reply);
-
}
-
//4.关闭资源
-
br.close();
-
is.close();
-
pw.close();
-
os.close();
-
socket.close();
-
-
} catch (UnknownHostException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
} catch (IOException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
-
}
-
}
我们运行测试一下,先运行服务器,再运行客户端。我们会看到,这次后台不只是客户端接收到了服务器给的请求信息,在服务器后台,也输出了相应的响应信息:我们可以点击下图所示的切换来查看客户端与服务器接收与响应的后台信息:
最后,我们来总结一下Socket中服务器与客户端的各步骤。
服务器端:
- 建立一个服务器Socket绑定指定的端口并开始监听;
- 使用accept()方法阻塞等待监听,获取新的连接;
- 建立输入和输出流;
- 在已有的协议上产生会话;
- 使用close()方法关闭流和Socket;
- 建立客户端Socket连接,指定服务器的位置以及端口;
- 得到Socket的读写流;
- 利用流按照一定的协议对Socket进行读/写操作;
- 使得close()方法关闭流和Socket
这是Socket网络编程之传递字符类型,接下来我会在我博客另外一篇中Socket升级传递对象编程