編寫小程序:向服務端上傳圖片
發送端:
接收端:
實現多個客戶端併發訪問服務端
將需要在服務端運行的代碼封裝到多線程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服務器上尋找