目前较为流行的网络编程模型是客户机/服务器(C/S架构),服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应并持续监听服务端口,
传输协议概述:
TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。
1)什么是socket?
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。,一个Socket由一个IP地址和一个端口号唯一确定。
2)创建socket
java在包java.net提供了两个类,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,。其构造方法如下:
Socket(InetAddress address, int port);
Socket(InetAddress address, int port, boolean stream);
Socket(String host, int prot);
Socket(String host, int prot, boolean stream);
Socket(SocketImpl impl)
Socket(String host, int port, InetAddress localAddr, int localPort)
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
ServerSocket(int port);
ServerSocket(int port, int backlog);
ServerSocket(int port, int backlog, InetAddress bindAddr)
其中address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和 bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可 以用来创建Socket。count则表示服务端所能支持的最大连接数。例如:
服务端代码:
package socketserver;
import java.io.*;
import java.net.*;
public class SocketServer {
// 为这个Socket选择一个断口8080:
public static final int PORT = 8099;
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(PORT);
System.out.println("开始: " + s);
try {
// 生成一个Socket等待连接请求
Socket socket = s.accept();
try {
System.out.println(
"接受连接请求: " + socket);
BufferedReader in =
new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// 定义一个PrintWriter对象写输出流
PrintWriter out =
new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())), true);
while (true) {
String str = in.readLine();
if (str.equals("END")) {
break;
}
System.out.println("自客户端: " + str);
out.println(str);
}
// 关闭socket
}
finally {
System.out.println("关闭...");
socket.close();
}
}
finally {
s.close();
}
}
}
客户端代码
package socketclient;
import java.io.*;
import java.net.*;
import socketserver.*;
public class SocketClient {
public static void main(String[] args) throws IOException {
// 指定使用本地IP
InetAddress addr =
InetAddress.getByName(null);
System.out.println("addr = " + addr);
Socket socket =
new Socket(addr,SocketServer.PORT);
// 将代码放在Try语句中执行,以确保程序能关闭socket
try {
System.out.println("socket = " + socket);
BufferedReader in =
new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// 定义一个PrintWriter对象写输出流
PrintWriter out =
new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())), true);
for (int i = 0; i < 10; i++) {
out.println("测试 " + i);
String str = in.readLine();
System.out.println("自服务端: " + str);
}
out.println("END");
}
finally {
System.out.println("关闭");
socket.close();
}
}
}