基于TCP的编程
先启动服务器再启动客户端(先启动客户端未找到服务器出错)
不能重复启动服务端(否则端口号冲突)
客户端:Socket 发送:用输出流
服务器:ServerScoket–>Socket 接收:用输入流
单向通信案例
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestSrerver {//服务器端
public static void main(String[] args) throws IOException {
System.out.println("----------------服务器端启动了-----------------");
//1.创建一个套接字,指定本侧的端口号
ServerSocket ss=new ServerSocket(8888);
//2.通过ServerSocket的accepet的方法,用来获取服务器端的套接字
Socket s=ss.accept();//阻塞方法
//3.对于服务端来说,我们是利用流来接收数据
InputStream is=s.getInputStream();
DataInputStream dis =new DataInputStream(is);
String str =dis.readUTF();
System.out.println("客户端来话了:"+str);
//4.关闭流,网络资源关闭
dis.close();
is.close();
s.close();
ss.close();
}
}
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class TestClient {//客户端
public static void main(String[] args) throws IOException {
System.out.println("-----------客户端启动了------------");
//1.创建Socket,用来发送请求的,指定服务器段的IP和端口号
Socket s=new Socket("localhost",8888);
//2.对于客户端来说,我们直观的感受是用流发送数据
OutputStream os =s.getOutputStream();
DataOutputStream dos =new DataOutputStream(os);
dos.writeUTF("你好啊,服务器");
//3.关闭流,关闭套接字资源
dos.close();
os.close();
s.close();
}
}
双向通信案例
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TestSrerver {//服务器端
public static void main(String[] args) throws IOException {
System.out.println("----------------服务器端启动了-----------------");
//1.创建一个套接字,指定本侧的端口号
ServerSocket ss=new ServerSocket(8888);
//2.通过ServerSocket的accepet的方法,用来获取服务器端的套接字
Socket s=ss.accept();//阻塞方法
//3.对于服务端来说,我们是利用流来接收数据
InputStream is=s.getInputStream();
DataInputStream dis =new DataInputStream(is);
String str =dis.readUTF();
System.out.println("客户端来话了:"+str);
//服务端对客户端的响应
s.shutdownInput();
OutputStream os =s.getOutputStream();
DataOutputStream dos =new DataOutputStream(os);
dos.writeUTF("服务器收到,你也好啊,客户端");
//4.关闭流,网络资源关闭
dis.close();
is.close();
s.close();
ss.close();
}
}
```java
import java.io.*;
import java.net.Socket;
public class TestClient {//客户端
public static void main(String[] args) throws IOException {
System.out.println("-----------客户端启动了------------");
//1.创建Socket,用来发送请求的,指定服务器段的IP和端口号
Socket s=new Socket("localhost",8888);
//2.对于客户端来说,我们直观的感受是用流发送数据
OutputStream os =s.getOutputStream();
DataOutputStream dos =new DataOutputStream(os);
dos.writeUTF("你好啊,服务器");
//客户端接收服务端数据
s.shutdownOutput();
InputStream is=s.getInputStream();
DataInputStream dis=new DataInputStream(is);
System.out.println("服务器端回应我了:"+dis.readUTF());
//3.关闭流,关闭套接字资源
dos.close();
os.close();
s.close();
}
}
多线程访问登录
//定义一个User类
import java.io.Serializable;
public class User implements Serializable {//序列化
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
//编写一个服务类
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TestSrerver {//服务器端
public static void main(String[] args) {
System.out.println("----------------服务器端启动了-----------------");
//1.创建一个套接字,指定本侧的端口号
ServerSocket ss= null;
Socket s=null;
//定义一个计数器,用来计算有多少个用户访问
int count=0;
try {
ss = new ServerSocket(8888);
while(true){
//2.通过ServerSocket的accepet的方法,用来获取服务器端的套接字
s=ss.accept();//阻塞方法
//每接收一个就是一个线程来处理,要用传参的构造方法,将s传过去
new ServerThread(s).start();
System.out.println("当前是第"+ (count++) +"个客户在访问,当前用户的ip是:"+s.getInetAddress());
}
} catch (IOException e) {
e.printStackTrace();
}
//因为要一直监听客户端发来的数据,所以s和ss就不需要关了
// } finally { //4.关闭流,网络资源关闭
// try {
// if ( s!=null)
// s.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// try {
// if ( ss!=null)
// ss.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
}
//给这个类提供一个多线程服务
import java.io.*;
import java.net.Socket;
public class ServerThread extends Thread{
Socket s=null;
InputStream is=null;
ObjectInputStream ois=null;
OutputStream os=null;
DataOutputStream dos=null;
public ServerThread(Socket s){
this.s=s;
}
@Override
public void run() {
//服务器处理逻辑的代码:
try {
//3.对于服务端来说,我们是利用流来接收数据
is=s.getInputStream();
ois =new ObjectInputStream(is);
User user=(User)(ois.readObject());
//进行校验:
String str =null;
if(user.getUsername().equals("lili")&&user.getPassword().equals("123123")){
str=("登录成功");
}else{
str="登陆失败";
}
//服务端对客户端的响应
s.shutdownInput();
os =s.getOutputStream();
dos =new DataOutputStream(os);
dos.writeUTF(str);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
{
try {
if (dos!=null)
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if ( os!=null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if ( ois!=null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if ( is!=null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//写一个客户端
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class TestClient {//客户端
public static void main(String[] args){
System.out.println("-----------客户端启动了------------");
//1.创建Socket,用来发送请求的,指定服务器段的IP和端口号
Socket s= null;
OutputStream os=null;
ObjectOutputStream oos=null;
InputStream is=null;
DataInputStream dis=null;
try {
s = new Socket("localhost",8888);
//录入账号密码
Scanner sc =new Scanner(System.in);
System.out.print("账号: ");
String username=sc.next();
System.out.print("密码: ");
String password=sc.next();
//将账号和密码封装成为User对象:
User user =new User(username,password);
//2.对于客户端来说,我们直观的感受是用流发送数据
os =s.getOutputStream();
oos =new ObjectOutputStream(os);
oos.writeObject(user);
//客户端接收服务端数据
s.shutdownOutput();
is=s.getInputStream();
dis =new DataInputStream(is);
System.out.println("登录的结果是:"+dis.readUTF());
} catch (IOException e) {
e.printStackTrace();
}finally {
//3.关闭流,关闭套接字资源
try {
if(dis!=null)
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(oos!=null)
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(os!=null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(s!=null)
s.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(is!=null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}