首先先来理解一下几个概念:
服务器:能够提供信息的计算机或程序。
客户机:请求信息的计算机或程序
当然,在现实生活中有时候区分客户机与服务器还是比较困难的。因为很多信息都是相互请求、互相提供信息的。
协议:为了保证两台以上的计算机可以顺利地通信,必须有某种相互都必须遵守的条约,计算机中称之为协议,例如我们平时所说的互联网协议。这种协议用四个字节来唯一的表示网络中的一台机器。
端口:网络设计程序中的端口并不是实际存在的,而是一个我们假想的连接器。端口被规定为0~65535之间的一个数。其中的1~1023段接口已经被系统所占用了,我们应该使用1024~65535之间的任意端口号,以免发生冲突。
套接字:网络程序中的套接字是将我们的应用程序与端口连接起来,这个也是一个假象的装置。
那么在JAVA中,我们怎样利用端口和套接字,在客户端和服务器端进行数据传递呢?
我们一般是创建Socket类的对象去使用套接字。接着我们可以利用Socket流对象进行数据传递。例如socket.getOutputStream()和socket.getInputStream();
1、服务器套接字应用
ServerSocket类表示服务器套接字。一般来说,服务器的套接字只可以与一个客户机的套接字相连,如果有多台客户机同时要求与服务器相连,则服务器套接字将会把客户机的套接字存进队列当中,从中按顺序连接。
ServerSocket类的常用构造函数有三个:
public ServerSocket(int port):使用指定的端口创建服务器套接字
public ServerSocket(int port,int backlog):使用指定的端口创建服务器套接字,backlog用来指定队列大小
public ServerSocket(int port,int backlog,InetAddress bindAddr):使用端口号,队列大小及指定的IP地址创建服务器套接字
ServerSocket类常用方法如下:
public Socket accept():等待客户机的请求,如果连接上了,就创建一个套接字,并且将其返回。
public void close():关闭服务器套接字
2、套接字实现
Socket类表示套接字,使用时要指定连接服务器的IP地址及端口号。这个是由客户机创建的,用于连接服务器。当客户机创建了Socket对象后,将立即向指定的端口号和IP地址发送请求连接。与此同时,服务器的套接字会创建新的套接字对象,然后与客户端的套接字连接起来。成功后便可以获取套接字的输入输出流,彼此进行数据交换。
Server类的构造函数有两个:
public Socket(string host,int port):创建指定连接的服务器的套接字,host为主机,port为端口号
public Socket(InetAddress address,int port):创建连接指定服务器的套接字,address表示IP地址对象,port为端口号
Server类常用方法如下:
public int getPort():获取端口号
public Inputstream getInputStream():获取套接字的输入流
public Outputstream getOutputStream():获取套接字的输出流
public synchorized void close():关闭套接字
这是一个关于服务器和客户端之间的输入输出流的关系图:
3、总结
(1)服务器端程序的编写
1、创建ServerSocket类的对象,利用构造函数ServerSocket(int port)创建一个套接字,并绑定到指定的端口port上。如ServerSocket s = new ServerSocket(2222);2222为端口号
2、调用ServerSocket的函数accept(),监听是否有客户端请求连接。如果有,则接受请求,并返回通信套接字。如Socket sk= s.accept();
3.调用Socket类的输入输出流函数,获取输入流和输出流,开始数据的发送和接受。如PrintStream ps = new PrintStream(sk.getOutputStream())和br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
4、关闭套接字。
(2)客户端程序的编写
1、调用socket类的构造函数,创建套接字,并且连接到服务器端。如:Socket sk =new Socket(“127.0.0.1”,2222);解释一下,127.0.0.1为我们本机的IP地址。,2222为端口号
2、调用Socket类的输入输出流函数,获取输入流和输出流,开始数据的发送和接受。如PrintStream ps = new PrintStream(sk.getOutputStream())和br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
3、关闭套接字。
4、有关代码
客户端的代码
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class Client
{
public static void main(String[] args)
{
try{
Socket sk =new Socket("127.0.0.1",2222);
System.out.println("客户端正在开启");
PrintStream p = new PrintStream(sk.getOutputStream());//将客户端套接字的输出流用printStream包装起来
System.out.print("请输入需要发送的内容:");
Scanner input = new Scanner(System.in);
String str = input.nextLine();//输入数据
p.println(str);//把控制台输入的内容送入被printstream类包装的输出流里面,发送到服务器里
p.close();//关闭输出流
sk.close();//关闭socket套接字
}
catch(Exception e){e.printStackTrace();}
}
}
这是服务器端的代码:
import java.io.*;
import java.net.*;
class Server extends Thread
{
Socket sk;
public Server(Socket sk)
{
this.sk= sk;
}
public void run()
{
BufferedReader br=null;
try{
br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
String str = br.readLine();
System.out.println("客户端的数据:"+str);
br.close();
sk.close();
}
catch(IOException e){e.printStackTrace();}
}
public static void main(String[] args) throws Exception
{
ServerSocket s = new ServerSocket(2222);//创建ServerSocket的套接字,准备与客户端进行连接
System.out.println("服务器正在等待客户端的连接");
//同时响应多个客户端的请求
while(true){
Socket sk= s.accept();//服务器监听输入
Server st = new Server(sk);//创建一个线程,用线程创建一个套接字
st.start();
}
}
}
结果图如下:
在客户端输入“王境泽说真香”,在服务器收到了数据
5、感想
在学习过程中,先后借鉴了很多网上大神的代码,在这里一一感谢这些大神们,没有他们我真的完成不了学校的java课程设计!!谢谢你们~笔芯!!