一,TCP介绍
TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。
二.基于Socket的java网络编程
1.什么是Socket
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。
但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
2.Socket通讯的过程
Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
(4) 关闭Socket.
三.服务端与客户端代码
1,首先实现服务端代码
package com.pengda.socket;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server1 {
public static void main(String[] args) {
try {
//1,创建一个服务器端socket 即 ServerSocket,指定绑定的端口,并监听此 端口
ServerSocket serverSocket = new ServerSocket(4567) ;
Socket socket = null ;
//记录客户端的数量
int count = 0 ;
System.out.println("---服务器端启动,等待客户端连接---");
while(true){
//调用 accept()方法监听,等待客户端连接
socket = serverSocket.accept() ;
//创建一个新线程
ServerThread serverThread = new ServerThread(socket) ;
//启动线程
serverThread.start() ;
count++ ;//统计客户端的数量
System.out.println("客户端的数量:"+count) ;
InetAddress inetAddress = socket.getInetAddress() ;
System.out.println("当前客户端的IP:"+inetAddress.getHostAddress());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2,实现客户端代码
package com.pengda.socket;
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 Client {
public static void main(String[] args) {
try {
//1,创建客户端Socket,指定服务器地址和端口
Socket socket = new Socket("localhost",4567) ;
//2,获取输出流,向服务器端发送信息
OutputStream os = socket.getOutputStream() ;//字节流输出
PrintWriter pw = new PrintWriter(os) ;//将字节流包装为打印流
pw.write("用户名:admin;密码:123") ;
pw.flush() ;
socket.shutdownOutput() ;//关闭输出流
//3,获取输入流,得到服务器端的输出流
InputStream is = socket.getInputStream() ;//字节流输入
InputStreamReader isr = new InputStreamReader(is) ;//将字节流转换为字符流
BufferedReader br = new BufferedReader(isr) ;
String info = "" ;
while((info=br.readLine())!=null){
System.out.println("我是客户端,服务器说:"+info);
}
//3,关闭资源
br.close();
isr.close();
is.close();
pw.close() ;
os.close() ;
socket.close() ;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3,使用多线程来实现服务器与客户端通信
package com.pengda.socket;
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;
public class ServerThread extends Thread {
Socket socket = null ;
public ServerThread(Socket socket){
this.socket = socket ;
}
//线程执行的操作,响应客户端的请求
public void run(){
InputStream is = null ;
InputStreamReader isr = null ;
BufferedReader br = null ;
OutputStream os = null ;
PrintWriter pw = null ;
try {
//获取输入流,字节流
is = socket.getInputStream() ;
//字节流转换为字符流
isr = new InputStreamReader(is) ;
//将字符流放入缓冲
br = new BufferedReader(isr) ;
//定义一个空字符串
String info = null ;
while((info=br.readLine())!=null){
System.out.println("我是服务端,客户端说:"+info);
}
socket.shutdownInput() ;//关闭输入流
//获取输出流
os = socket.getOutputStream() ;
pw = new PrintWriter(os) ;
pw.write("欢迎你!") ;
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(pw !=null){
pw.close();
}
if(os!=null){
os.close() ;
}
if(br!=null){
br.close();
}
if(isr!=null){
isr.close() ;
}
if(is!=null){
is.close() ;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
四,运行时,要先运行服务端,再运行客户端,就能输出通信的内容