编写小程序:向服务端上传图片
发送端:
接收端:
实现多个客户端并发访问服务端
将需要在服务端运行的代码封装到多线程run()方法中
客户端:import java.io.*;
import java.net.*;
public class PicClient {
public static void main(String[] args) throws UnknownHostException,
IOException {
// System.out.println(InetAddress.getLocalHost().getHostAddress());
Socket s = new Socket("10.1.41.123", 10012);
// 读取本地图片流对象
FileInputStream fis = new FileInputStream("F:\\2\\cloud.jpg");
// 传输输出流对象
OutputStream osOut = s.getOutputStream();
// 读取反馈信息
InputStream isIn = s.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
osOut.write(buf, 0, len);
}
// 传输结束,加个结束标记
s.shutdownOutput();
// 读取服务器返回的信息
byte[] b = new byte[1024];
int num = 0;
num = isIn.read(b);
String str = new String(b, 0, num);
System.out.println(str);
fis.close();
s.close();
}
}
服务端:
import java.io.*;
import java.net.*;
class PicUpload implements Runnable {
private Socket s = null;
public PicUpload(Socket s) {
this.s = s;
}
public void run() {
// 定义计数器,用来给文件命名
int count = 1;
InputStream isIn = null;
FileOutputStream fos = null;
OutputStream osOut = null;
File file = null;
try {
// 指定文件名
String ip = s.getLocalAddress().getHostAddress();
file = new File("F:\\3\\" + ip + "(" + count + ")" + ".jpg");
while (file.exists()) {
count++;
file = new File("F:\\3\\" + ip + "(" + count + ")" + ".jpg");
}
isIn = s.getInputStream();
osOut = s.getOutputStream();
fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while ((len = isIn.read(buf)) != -1) {
fos.write(buf, 0, len);
}
osOut.write("上传成功".getBytes());
fos.close();
s.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class PicServer1 {
// 同时为多个客户服务,将服务代码封装到多线程中
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10012);
while (true) {
Socket s = ss.accept();
new Thread(new PicUpload(s)).start();
}
}
}
实现多个客户端并发访问服务端
将需要在服务端运行的代码封装到多线程run()方法中
客户端:
客户端键盘录入用户名
服务端对这个用户名进行校验
如果用户存在,在服务端显示xxx,已经登录
并在客户端显示xxx,欢迎光临
如果该用户不存在没在服务端显示xxx,尝试登录
并在客户端显示xxx,该用户不存在
最多登录三次
客户端代码:import java.io.*;
import java.net.Socket;
public class UserClient {
// 模拟客户登录
/*
* 1,键盘录入用户名,只能录入三次 2,将用户名发向服务端, 在服务端验证 3,接收服务端反馈消息
*/
public static void main(String[] args) throws Exception {
Socket s = new Socket("10.1.41.123", 10013);
// 键盘读取用户名的流对象
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 向客户端传送用户名信息的流对象
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
// 读取服务器反馈信息的流对象
BufferedReader brIn = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 只能登录三次,限制键盘录入三次用户名
for (int i = 0; i < 3; i++) {
String line = br.readLine();
// 如果键盘录入为null,则跳出本次循环
if (line == null) {
break;
}
pw.println(line);
String str = null;
str = brIn.readLine();
System.out.println(str);
// 如果已经登录成功,则不用再登录了,跳出循环,不然的话,服务器那边已经关闭资源,客户端会出现异常
if (str.contains("欢迎")) {
break;
}
}
br.close();
s.close();
}
}
服务端代码:
import java.io.*;
import java.net.*;
class UserLogin implements Runnable {
private Socket s = null;
public UserLogin(Socket s) {
this.s = s;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 服务器也限定只验证三次
BufferedReader br = null;
try {
for (int i = 0; i < 3; i++) {
// 读取本地用户名信息
br = new BufferedReader(new FileReader("F:\\3\\users.txt"));
// 接收客户端传来的用户名
BufferedReader brIn = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 创建向客户端发送反馈信息的流对象
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
boolean flag = false;
String name = brIn.readLine();
if (name == null) {
break;
}
String line = null;
while ((line = br.readLine()) != null) {
if (name.equals(line)) {
flag = true;
break;
}
}
if (flag) {
System.out.println(name + ",用户已经登录");
pw.println(name + "欢迎光临");
break;
} else {
System.out.println(name + "尝试登录");
pw.println(name + ",用户名不存在");
}
br.close();
}
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class UserServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10013);
while (true) {
Socket s = ss.accept();
new Thread(new UserLogin(s)).start();
}
}
}
客户端向服务器发送的信息,详细解释(http请求消息头)
通过get请求方式,访问根目录/
GET / HTTP/1.1
告诉服务器要访问的地址及端口
Host: localhost:11000
Connection: keep-alive
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
用户信息
User-Agent: Mozilla/5.0 (Windows NT6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71Safari/537.36
支持的压缩格式
Accept-Encoding: gzip,deflate,sdch
支持的语言
Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4
地址解析:
主机名映射对应的ip地址
www.baidu.com(将主机名翻译成相应的ip地址,需要域名解析,通过DNS服务器解析主机名)
DNS服务器:
存放着地址映射表,记录着主机名和对应的ip地址,该服务器用于返回ip地址,然后客户端通过该返回的ip去访问对应的主机
在本地也有记录映射关系的表
C:\Windows\System32\drivers\etc\host
访问主机时,先在本地寻找映射关系,然后再到DNS服务器上寻找