网络编程又可以称之为socket编程。网络编程的三要素是指:IP地址,端口号和协议(UDP和TCP)。
一、UDP编程
1、使用UDP发送数据的流程分别是:
创建发送端Socket对象:
DatagramSocket datagramSocket = new DatagramSocket(); //随机分配端口号
DatagramSocket(int port)//创建Socket对象并制定端口号
创建数据并打包:
DatagramPacket message = new DatagramPacket(bys, length,address,port);
发送数据:
datagramSocket.send(message);
释放资源:datagramSocket.close();
完整的代码如下所示:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//创建发送端Socket对象
DatagramSocket datagramSocket = new DatagramSocket();
// 创建数据并打包
/**
* DatagramPacket:表示一个数据包
* byte[]:数据
* 目的设备地址:ip
* 目的设备端口号
*/
String s = "hello,udp,im coming";
byte[] bys = s.getBytes();//将信息转换为字节数组
int length = bys.length; //获取字节数组的长度
InetAddress address = InetAddress.getByName("gblcs"); //自己发给自己
int port = 8888; //设置目的端口号
DatagramPacket message = new DatagramPacket(bys, length,address,port);
//发送数据
datagramSocket.send(message);
//释放资源
datagramSocket.close();
}
2、使用UDP接收数据
创建接收端Socket对象:DatagramSocket datagramSocket = new DatagramSocket(8888);
接收数据:DatagramPacket dp = new DatagramPacket(bys, bys.length);
datagramSocket.receive(dp);
解析数据:InetAddress address = dp.getAddress(); //获取发送端地址
byte[] data = dp.getData(); //获取发送数据
int length = dp.getLength(); //获取长度
输出数据:System.out.println("send------>"+address);
System.out.println("data------>"+new String(data,0,length));
释放资源:datagramSocket.close(); //服务器中的服务可以不用关闭
完整的代码如下所示:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//创建接收端Socket对象
DatagramSocket datagramSocket = new DatagramSocket(8888);
// 接收数据
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
datagramSocket.receive(dp);
// 解析数据
InetAddress address = dp.getAddress(); //获取发送端地址
byte[] data = dp.getData(); //获取发送数据
int length = dp.getLength(); //获取长度
//输出数据
System.out.println("send------>"+address);
System.out.println("data------>"+new String(data,0,length));
//释放资源
datagramSocket.close();
}
二、使用TCP编程
1、使用TCP发送数据
创建发送端Socket对象(创建连接):Socket s = new Socket(InetAddress.getByName("gblcs"),9999); //参数为主机名和端口号
获取输出流对象:OutputStream os = s.getOutputStream();
发送数据:os.write("hello,tcp,im coming".getBytes());
释放资源:s.close();
完整代码如下:
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
//创建发送端socket对象
Socket s = new Socket(InetAddress.getByName("gblcs"),9999);
//创建输出流对象
OutputStream os = s.getOutputStream();
//发送数据
os.write("hello,tcp,im coming".getBytes());
//释放资源
s.close();
}
2、使用TCP接收数据
创建接收端Socket对象:ServerSocket ss = new ServerSocket(9999);
监听(等待客户端发送数据):Socket s = ss.accept();
获取输入流对象:InputStream is = s.getInputStream();
输出数据:int len = is.read(bys);
System.out.println("Client------->"+s.getInetAddress().getHostAddress());
System.out.println(new String(bys,0,len));
释放资源:s.close();
完整代码如下所示:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept();
InputStream is = s.getInputStream();
byte [] bys = new byte[1024];
int len = is.read(bys);
System.out.println("Client------->"+s.getInetAddress().getHostAddress());
System.out.println(new String(bys,0,len));
s.close();
}
三、写一个Demo,使用TCP协议完成用户登录操作(模拟数据库)。从键盘上输入用户名和密码,进行验证,正确返回“登陆成功”,错误返回“登录失败”。
创建User对象:
public class User {
private String username;
private String password;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String username, String password) {
super();
this.username = username;
this.password = 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;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
}
创建UserDB对象(模拟数据库):
public class UserDB {
private static List<User> users = new ArrayList<User>();
static{
users.add(new User("zhangsan","1234"));
users.add(new User("lisi","1234"));
users.add(new User("liuliu","12345"));
}
public static List<User> getUsers(){
return users;
}
}
创建Client类:
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
//创建客户端socket对象
Socket s = new Socket("gblcs",9999);
//获取用户名和密码
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名 ");
String name = br.readLine();
System.out.println("请输入密码");
String password = br.readLine();
//获取输出流对象
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
//写出数据
pw.println(name);
pw.println(password);
//获取输入流对象
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(s.getInputStream()));
//返回服务器的数据
String reslut = bufferedReader.readLine();
System.out.println(reslut);
//关闭资源
s.close();
}
创建Service类:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//创建服务器socket
ServerSocket ss = new ServerSocket(9999);
//监听
Socket s = ss.accept();
//获取输入流对象
BufferedReader bf = new BufferedReader(new InputStreamReader(s.getInputStream()));
//获取用户名和密码
String username = bf.readLine();
//System.out.println(username);
String password = bf.readLine();
//System.out.println(password);
//判断用户名和密码是否正确
boolean flag = false;
List<User> users = UserDB.getUsers();
User user = new User(username,password);
if(users.contains(user)){
flag = true;
}
//获取输出流
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
//返回判断信息
if(flag){
pw.println("登录成功");
}else {
pw.println("登录失败");
}
//释放资源
s.close();
}
}