TCP编程
服务器tcp编程步骤:
- 1.指定端口。使用ServerSocket创建服务器
- 2.阻塞式等待连接accept
- 3.操作:输入输出流操作
- 4.释放资源
客户端TCP编程步骤:
- 1.建立连接:使用Socket创建客户端,指定服务器的地址和端口
- 2.操作:输入输出流操作
- 3.释放资源
利用TCP编程,实现模拟多个用户的登陆:可以开启多个客户端,提交登录信息,服务器根据内容进行判断,并且返回结果
服务器端
public class LoginMulServer {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
System.out.println("------Server------");
//1.指定端口。使用ServerSocket创建服务器
ServerSocket server=new ServerSocket(8888);
// 2.阻塞式等待连接accept
while(true){
Socket client=server.accept();
System.out.println("一个客户端建立了");
new Thread(new Channal(client) ).start();
}
}
//一般不关闭服务端。
static class Channal implements Runnable{
private Socket client;
private DataInputStream dis;//输入流封装
private DataOutputStream dos;//输出流
public Channal(Socket client) {
this.client=client;
try {
dis = new DataInputStream(client.getInputStream());
dos=new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
client.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
//封装一个返回数据的方法,提供给run方法内部使用
private String receive() {
String datas="";
try {
datas = dis.readUTF();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return datas;
}
//封装一个发送数据的方法
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//封装一个方法释放资源
private void release() {
try {
if(null!=dos)
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(null!=dis)
dis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(null!=client)
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
String datas=receive();
//分析数据
String[] dataArray=datas.split("&");
for(String info:dataArray) {//遍历字符串数组,获得用户名和密码
String[] user=info.split("=");
System.out.println(user[0]+"---->"+user[1]);
}
String uname=dataArray[0].substring(6);
String upw=dataArray[1].substring(9);
//输出
if(uname.equals("lsy")&&upw.equals("1234")) {
send("登录正确");
}else {
send("用户名或者密码错误");
}
// 4.释放资源
release();
}
}
}
客户端
public class LoginMulClient {
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
System.out.println("------client------");
BufferedReader console=new BufferedReader(new InputStreamReader(System.in));
// 1.建立连接:使用Socket创建客户端,指定服务器的地址和端口
Socket client=new Socket("localhost",8888);//指定本机的服务器,端口号
// 2.操作:输出流操作
//创建DataOutputStream,方便写入数据,可以指定相应的类型
//控制台获得用户名和密码
System.out.println("请输入用户名:");
String uname=console.readLine();
System.out.println("请输入密码:");
String passward=console.readLine();
new Send(client).send("uname="+uname+"&"+"passward="+passward);
//接受结果
new Receive(client).receive();
// 3.释放资源
client.close();
}
//发送
static class Send{
private DataOutputStream dos;
private Socket client;
public Send(Socket client) {
this.client=client;
try {
dos=new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//接收
static class Receive{
private DataInputStream dis;
private Socket client;
public Receive(Socket client) {
this.client=client;
try {
dis=new DataInputStream(client.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void receive() {
String datas;
try {
datas = dis.readUTF();
System.out.println(datas);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
UDP编程:
接收端:服务器
- 1.使用DataGramSocket指定端口,创建接收端
- 2.准备容器,封装成DataGramPocket包裹
- 3.阻塞式接受包裹receive(DataGramPocket p)
- 4.分析数据;一切都是对于字节数组的操作
byte[] get Data
getlength() - 5.释放资源
发送端:客户端
- 1.使用DatagramSocket指定端口,创建发送端
- 2.准备数据,一定转成字节数组
- 3.封装成DatagramPacket包裹,需要指定目的地
- 4.发送包裹send(DatagramPacket p)
- 5.释放资源
模拟一个聊天室,将老师作为服务器端,学生作为客户端,实现两个人的对话
使用多线程实现双向交流
学生端
public class TalkStudent {
public static void main(String[] args) {
// TODO Auto-generated method stub
//发送端口,本机,接收端口
new Thread(new TalkSend(7777,"localhost",9999)).start();//发送
new Thread(new TalkReceive(8888,"老师")).start();//接收,指定服务端口
}
}
教师端
public class talkTeacher {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new TalkReceive(9999,"学生")).start();//接收,指定服务端口
new Thread(new TalkSend(5555,"localhost",8888)).start();//发送,发送端口,本机,接收端口
}
}
使用面向对象封装发送端和接收端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class TalkSend implements Runnable {
private DatagramSocket client;
private BufferedReader reader;
private String toIp;//对方的IP地址
private int toPort;
public TalkSend(int port,String toIp,int toPort) {//传入发送的窗口
this.toPort=toPort;
this.toIp=toIp;
try {
client=new DatagramSocket(port) ;
reader=new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
String data;
try {
// 2.准备数据,一定转成字节数组
//利用控制台输入,进行多次的输入。
data = reader.readLine();
byte[] datas=data.getBytes();
// 3.封装成DataGramPocket包裹,需要指定目的地
DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
new InetSocketAddress(this.toIp,this.toPort));//指定本机的地址和对方的端口号
// 4.发送包裹send(DataGramPocket p)
client.send(packet);
if(data.equals("bye")) {
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//从控制台输入一行。
}
// 5.释放资源
client.close();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class TalkReceive implements Runnable {
private DatagramSocket server ;
private String from;
public TalkReceive(int port,String from) {
this.from=from;
try {
server =new DatagramSocket(port);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
byte[] container=new byte[1024*60];
DatagramPacket packet=new DatagramPacket(container,0,container.length);
// 3.阻塞式接受包裹receive(DataGramPocket p)
try {
server.receive(packet);
//阻塞式
// 4.分析数据;一切都是对于字节数组的操作
byte[] datas=packet.getData();
int len=packet.getLength();
String data=new String(datas,0,len);
System.out.println(from+":"+data);
if(data.equals("bye")) {
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 5.释放资源
server.close();
}
}