网络通信之Socket编程
最近又从新接触了网络编程的知识,记得在大一下学期就已经接触了点网络编程,但是当时刚刚开始学java内功和招式都非常浅薄。所以当时处于一种非常尴尬的处境,以至于但是只有搬出数据照抄源码的境地。所以时隔半载功力和招式已经不可同日而语,为了纪念当时因内力不足而被招式反噬的苦逼境地,写出自己对网络编程的感悟。
首先来了解什么是Socket。所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。以J2SDK-1.3为例,Socket和ServerSocket类库位于java .net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
然后再看Socket客户端的创建
Socket(InetAddress remoteAddr, int remotePort)
Socket(String remoteHost, int remotePort)
Socket(InetAddress remoteAddr, int remotePort,InetAddress localAddr, int localPort)
Socket(String remoteHost, int remotePort, InetAddress localAddr, in localPort)
Socket()
前四个构造函数在创建了一个TCP套接字后,先连接到远程地址和端口号,再将其返回给程序。前两个没有指定本地的地址和端口号,将使用默认地址和可用的端口号。在有多个接口的主机上指定本地地址是有用的。指定地址的参数可以是字符串或InetAddress对象。最后一个没有创建连接,则在使用之前,必须显式的进行连接。
Socket: 操作
//使指定的终端打开一个TCP连接。SocketAdress是针对TCP/IP套接字的特殊型
void connect(SocketAddress destination)
void connect(SocketAddress destination, int timeout)
//取得输入流
InputStream getInputStream()
//取得输出流
OutputStream getOutputStream()
//关闭套接字,以及相关的输入输出
void close()
下面是一个建立客户端的代码示例:
public class ClientDemo {
public static void main(String[] arges) {
try {
// 获取一个IP。null表示本机
InetAddress addr = InetAddress.getByName(null);
// 打开8888端口,与服务器建立连接
Socket sk = new Socket(addr, 8888);
/*
* 上面这句也可以用 Socket sk = new Socket ("127.0.0.1", 8888); 代替
*/
// 缓存输入
BufferedReader in = new BufferedReader(new InputStreamReader(sk
.getInputStream()));
// 缓存输出
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(sk.getOutputStream())), true);
// 向服务器发送信息
out.println("你好!");
// 接收服务器信息
System.out.println(in.readLine());
//关闭套接字
sk.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
TCP服务端
服务器端的工作时间里一个通信 终端,并被动的等待客户端的连接。一般的一个服务器端的创建有以下两步工作:
1.创建一个ServerSocket实例并指定本地端口号
2.重复执行:
a.调用ServerSocket的accept()方法来监听下一个客户端的连接。并会返回一个Socket连接对象
b.用返回得到的Socket对象得到InputStream和OutputSream对象来进行与客户端的通信。
c. 通信完成后,使用Socket类的close()方法关闭该客户端套接字连接。
看服务段代码:
/**
* 这个服务器端非常简单,只连接一个客户端
* 并只接受一次客户端的消息,并向客户端发送一条消息
*/
public class SampleServer{
public static void main(String[] arges){
try{
int port = 8888;
//使用8888端口创建一个ServerSocket
ServerSocket mySocket = new ServerSocket(port);
//等待监听是否有客户端连接
while(true){
Socket sk = mySocket.accept();
//输入缓存
BufferedReader in = new BufferedReader (
new InputStreamReader (sk.getInputStream ()));
//输出缓存
PrintWriter out = new PrintWriter (
new BufferedWriter(
new OutputStreamWriter(
sk.getOutputStream ())), true);
//打印接收到的客户端发送过来的信息
System.out.println("客户端信息:"+in.readLine ());
//向客户端回信息
out.println("你好,我是服务器。我使用的端口号: "+port);
}
}catch(Exception e){
System.out.println(e);
}
}
}
下面的程序是实现的界面板的一对一的聊天程序。
实现代码在附件中。
接着实现的例子是使用多线程,多客户端聊天的程序
实现代码见附件
通过上面的例子,我们大概知道了服务器和客户端之间的通信关系,但是这些只是浅层次表面上的知识,更深层的还要了解TCP/IP的工作原理。