Transmission Control Protocol/Internet Protocol的簡寫,中譯名為傳輸控制協(xié)議/因特網(wǎng)互聯(lián)協(xié)議,又名網(wǎng)絡(luò)通訊協(xié)議,是Internet最基本的協(xié)議、Internet國際互聯(lián)網(wǎng)絡(luò)的基礎(chǔ),由網(wǎng)絡(luò)層的IP協(xié)議和傳輸層的TCP協(xié)議組成。TCP/IP 定義了電子設(shè)備如何連入因特網(wǎng),以及數(shù)據(jù)如何在它們之間傳輸?shù)臉?biāo)準(zhǔn)。協(xié)議采用了4層的層級結(jié)構(gòu),每一層都呼叫它的下一層所提供的協(xié)議來完成自己的需求。通俗而言:TCP負(fù)責(zé)發(fā)現(xiàn)傳輸?shù)膯栴},一有問題就發(fā)出信號,要求重新傳輸,直到所有數(shù)據(jù)安全正確地傳輸?shù)侥康牡?。而IP是給因特網(wǎng)的每一臺聯(lián)網(wǎng)設(shè)備規(guī)定一個地址。
通俗的說TCP/IP就是一些列的網(wǎng)絡(luò)通訊規(guī)則。
在TCP/IP參考模型中,將網(wǎng)絡(luò)分為以下幾層:
應(yīng)用層
傳輸層
網(wǎng)際層
主機至網(wǎng)絡(luò)層
而java中的網(wǎng)絡(luò)編程一般是在傳輸層,而其他情況下都是在應(yīng)用層進行開發(fā)(如java web/android的App開發(fā)等等)
網(wǎng)絡(luò)通訊要素
IP地址:InetAddress
-網(wǎng)絡(luò)中設(shè)備的標(biāo)識
-不易記憶,可用主機名
-本地回環(huán)地址:127.0.0.1 主機名:localhost
端口號
-用于標(biāo)識進程的邏輯地址,不同進程的標(biāo)識
-有效端口:0~65535,其中0~1024系統(tǒng)使用或保留端口。
傳輸協(xié)議
-通訊的規(guī)則
-常見協(xié)議:TCP,UDP
class IPDemo {
public static void main(String[] args) throws Exception {
// 返回本機主機名
// InetAddress i = InetAddress.getLocalHost();
// System.out.println(i.toString());
// System.out.println("address:"+i.getHostAddress());
// System.out.println("name:"+i.getHostName());
InetAddress ia = InetAddress.getByName("thinkpad-sl400");
System.out.println("address:" + ia.getHostAddress());
System.out.println("name:" + ia.getHostName());
}
}
UDP與TCP
UDP的特點
- 將數(shù)據(jù)及源和目的封裝成數(shù)據(jù)包中,不需要建立連接
- 每個數(shù)據(jù)報的大小在限制在64k內(nèi)
- 因無連接,是不可靠協(xié)議
- 不需要建立連接,速度快
面向無連接,不管對方在不在都會發(fā)送數(shù)據(jù),而且數(shù)據(jù)容易丟失
TCP的特點:
建立連接,形成傳輸數(shù)據(jù)的通道。
在連接中進行大數(shù)據(jù)量傳輸
通過三次握手完成連接,是可靠協(xié)議
必須建立連接,效率會稍低
Socket
Socket就是為網(wǎng)絡(luò)服務(wù)提供的一種機制。
通信的兩端都有Socket。
網(wǎng)絡(luò)通信其實就是Socket間的通信。
數(shù)據(jù)在兩個Socket間通過IO傳輸。
UDP傳輸?shù)氖褂茫?/h3>
1、DatagramSocket與DatagramPacket
2、建立發(fā)送端,接收端。
3、建立數(shù)據(jù)包。
4、調(diào)用Socket的發(fā)送接收方法。
5、關(guān)閉Socket。
發(fā)送端與接收端是兩個獨立的運行程序
1、DatagramSocket與DatagramPacket
2、建立發(fā)送端,接收端。
3、建立數(shù)據(jù)包。
4、調(diào)用Socket的發(fā)送接收方法。
5、關(guān)閉Socket。
發(fā)送端與接收端是兩個獨立的運行程序
UDP的使用Demo1:
需求:通過udp傳輸方式,將一段文字?jǐn)?shù)據(jù)發(fā)送出去。,
定義一個udp發(fā)送端。
思路:
1,建立updsocket服務(wù)。
2,提供數(shù)據(jù),并將數(shù)據(jù)封裝到數(shù)據(jù)包中。
3,通過socket服務(wù)的發(fā)送功能,將數(shù)據(jù)包發(fā)出去。
4,關(guān)閉資源。
代碼如下:
class UdpSend {
public static void main(String[] args) throws Exception {
// 1,創(chuàng)建udp服務(wù)。通過DatagramSocket對象。
DatagramSocket ds = new DatagramSocket(8888);
// 2,確定數(shù)據(jù),并封裝成數(shù)據(jù)包。DatagramPacket(byte[] buf, int length, InetAddress
// address, int port)
byte[] buf = "udp ge men lai le ".getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.254"), 10000);
// 3,通過socket服務(wù),將已有的數(shù)據(jù)包發(fā)送出去。通過send方法。
ds.send(dp);
// 4,關(guān)閉資源。
ds.close();
}
}
/*
* 需求: 定義一個應(yīng)用程序,用于接收udp協(xié)議傳輸?shù)臄?shù)據(jù)并處理的。
* 定義udp的接收端。 思路: 1,定義udpsocket服務(wù)。通常會監(jiān)聽一個端口。其實就是給這個接收網(wǎng)絡(luò)應(yīng)用程序定義數(shù)字標(biāo)識。
* 方便于明確哪些數(shù)據(jù)過來該應(yīng)用程序可以處理。
* 2,定義一個數(shù)據(jù)包,因為要存儲接收到的字節(jié)數(shù)據(jù)。 因為數(shù)據(jù)包對象中有更多功能可以提取字節(jié)數(shù)據(jù)中的不同數(shù)據(jù)信息。
* 3,通過socket服務(wù)的receive方法將收到的數(shù)據(jù)存入已定義好的數(shù)據(jù)包中。 4,通過數(shù)據(jù)包對象的特有功能。將這些不同的數(shù)據(jù)取出。打印在控制臺上。
* 5,關(guān)閉資源。
*/
class UdpRece {
public static void main(String[] args) throws Exception {
// 1,創(chuàng)建udp socket,建立端點。
DatagramSocket ds = new DatagramSocket(10000);
while (true) {
// 2,定義數(shù)據(jù)包。用于存儲數(shù)據(jù)。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
// 3,通過服務(wù)的receive方法將收到數(shù)據(jù)存入數(shù)據(jù)包中。
ds.receive(dp);// 阻塞式方法。
// 4,通過數(shù)據(jù)包的方法獲取其中的數(shù)據(jù)。
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(), 0, dp.getLength());
int port = dp.getPort();
System.out.println(ip + "::" + data + "::" + port);
}
// 5,關(guān)閉資源
// ds.close();
}
}
建議的UDP聊天工具:
/*
* 編寫一個聊天程序。 有收數(shù)據(jù)的部分,和發(fā)數(shù)據(jù)的部分。 這兩部分需要同時執(zhí)行。 那就需要用到多線程技術(shù)。 一個線程控制收,一個線程控制發(fā)。
* 因為收和發(fā)動作是不一致的,所以要定義兩個run方法。 而且這兩個方法要封裝到不同的類中。
*/
import java.io.*;
import java.net.*;
class Send implements Runnable {
private DatagramSocket ds;
public Send(DatagramSocket ds) {
this.ds = ds;
}
public void run() {
try {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = bufr.readLine()) != null) {
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.255"), 10002);
ds.send(dp);
if ("886".equals(line))
break;
}
} catch (Exception e) {
throw new RuntimeException("發(fā)送端失敗");
}
}
}
class Rece implements Runnable {
private DatagramSocket ds;
public Rece(DatagramSocket ds) {
this.ds = ds;
}
public void run() {
try {
while (true) {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(), 0, dp.getLength());
if ("886".equals(data)) {
System.out.println(ip + "....離開聊天室");
break;
}
System.out.println(ip + ":" + data);
}
} catch (Exception e) {
throw new RuntimeException("接收端失敗");
}
}
}
class ChatDemo {
public static void main(String[] args) throws Exception {
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10002);
new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();
}
}
TCP的使用
1、Socket和ServerSocket
2、建立客戶端和服務(wù)器端
3、建立連接后,通過Socket中的IO流進行數(shù)據(jù)的傳輸
4、關(guān)閉socket
同樣,客戶端與服務(wù)器端是兩個獨立的應(yīng)用程序。
TCP鏈接可以用三次握手兩次揮手來形容。
TCP使用Demo1:
/*
* 演示tcp傳輸。
* 1,tcp分客戶端和服務(wù)端。 2,客戶端對應(yīng)的對象是Socket。 服務(wù)端對應(yīng)的對象是ServerSocket。
*/
/*
* 客戶端, 通過查閱socket對象,發(fā)現(xiàn)在該對象建立時,就可以去連接指定主機。 因為tcp是面向連接的。所以在建立socket服務(wù)時,
* 就要有服務(wù)端存在,并連接成功。形成通路后,在該通道進行數(shù)據(jù)的傳輸。
* 需求:給服務(wù)端發(fā)送給一個文本數(shù)據(jù)。
* 步驟: 1,創(chuàng)建Socket服務(wù)。并指定要連接的主機和端口。
*
*/
import java.io.*;
import java.net.*;
class TcpClient {
public static void main(String[] args) throws Exception {
// 創(chuàng)建客戶端的socket服務(wù)。指定目的主機和端口
Socket s = new Socket("192.168.1.254", 10003);
// 為了發(fā)送數(shù)據(jù),應(yīng)該獲取socket流中的輸出流。
OutputStream out = s.getOutputStream();
out.write("tcp ge men lai le ".getBytes());
s.close();
}
}
/*
* 需求:定義端點接收數(shù)據(jù)并打印在控制臺上。
* 服務(wù)端: 1,建立服務(wù)端的socket服務(wù)。ServerSocket(); 并監(jiān)聽一個端口。 2,獲取連接過來的客戶端對象。
* 通過ServerSokcet的 accept方法。沒有連接就會等,所以這個方法阻塞式的。
* 3,客戶端如果發(fā)過來數(shù)據(jù),那么服務(wù)端要使用對應(yīng)的客戶端對象,并獲取到該客戶端對象的讀取流來讀取發(fā)過來的數(shù)據(jù)。 并打印在控制臺。
* 4,關(guān)閉服務(wù)端。(可選)
*/
class TcpServer {
public static void main(String[] args) throws Exception {
// 建立服務(wù)端socket服務(wù)。并監(jiān)聽一個端口。
ServerSocket ss = new ServerSocket(10003);
// 通過accept方法獲取連接過來的客戶端對象。
while (true) {
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + ".....connected");
// 獲取客戶端發(fā)送過來的數(shù)據(jù),那么要使用客戶端對象的讀取流來讀取數(shù)據(jù)。
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len));
s.close();// 關(guān)閉客戶端.
}
// ss.close();
}
}
TCP使用demo2:
import java.io.*;
import java.net.*;
/*
* 演示tcp的傳輸?shù)目蛻舳撕头?wù)端的互訪。
* 需求:客戶端給服務(wù)端發(fā)送數(shù)據(jù),服務(wù)端收到后,給客戶端反饋信息。
*/
/*
* 客戶端: 1,建立socket服務(wù)。指定要連接主機和端口。 2,獲取socket流中的輸出流。將數(shù)據(jù)寫到該流中。通過網(wǎng)絡(luò)發(fā)送給服務(wù)端。
* 3,獲取socket流中的輸入流,將服務(wù)端反饋的數(shù)據(jù)獲取到,并打印。 4,關(guān)閉客戶端資源。
*
*/
class TcpClient2 {
public static void main(String[] args) throws Exception {
Socket s = new Socket("192.168.1.254", 10004);
OutputStream out = s.getOutputStream();
out.write("服務(wù)端,你好".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len));
s.close();
}
}
class TcpServer2 {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10004);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "....connected");
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len));
OutputStream out = s.getOutputStream();
Thread.sleep(10000);
out.write("哥們收到,你也好".getBytes());
s.close();
ss.close();
}
}
TCP使用Demo3:
/*
* 需求:建立一個文本轉(zhuǎn)換服務(wù)器。 客戶端給服務(wù)端發(fā)送文本,服務(wù)單會將文本轉(zhuǎn)成大寫在返回給客戶端。
* 而且客戶度可以不斷的進行文本轉(zhuǎn)換。當(dāng)客戶端輸入over時,轉(zhuǎn)換結(jié)束。
* 分析: 客戶端: 既然是操作設(shè)備上的數(shù)據(jù),那么就可以使用io技術(shù),并按照io的操作規(guī)律來思考。 源:鍵盤錄入。 目的:網(wǎng)絡(luò)設(shè)備,網(wǎng)絡(luò)輸出流。
* 而且操作的是文本數(shù)據(jù)??梢赃x擇字符流。
* 步驟 1,建立服務(wù)。 2,獲取鍵盤錄入。 3,將數(shù)據(jù)發(fā)給服務(wù)端。 4,后去服務(wù)端返回的大寫數(shù)據(jù)。 5,結(jié)束,關(guān)資源。
* 都是文本數(shù)據(jù),可以使用字符流進行操作,同時提高效率,加入緩沖。
*/
import java.io.*;
import java.net.*;
class TransClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket("192.168.1.254", 10005);
// 定義讀取鍵盤數(shù)據(jù)的流對象。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
// 定義目的,將數(shù)據(jù)寫入到socket輸出流。發(fā)給服務(wù)端。
// BufferedWriter bufOut =
// new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
// 定義一個socket讀取流,讀取服務(wù)端返回的大寫信息。
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
out.println(line);
// bufOut.write(line);
// bufOut.newLine();
// bufOut.flush();
String str = bufIn.readLine();
System.out.println("server:" + str);
}
bufr.close();
s.close();
}
}
/*
* 服務(wù)端: 源:socket讀取流。 目的:socket輸出流。 都是文本,裝飾。
*/
class TransServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10005);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "....connected");
// 讀取socket讀取流中的數(shù)據(jù)。
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
// 目的。socket輸出流。將大寫數(shù)據(jù)寫入到socket輸出流,并發(fā)送給客戶端。
// BufferedWriter bufOut =
// new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
String line = null;
while ((line = bufIn.readLine()) != null) {
System.out.println(line);
out.println(line.toUpperCase());
// bufOut.write(line.toUpperCase());
// bufOut.newLine();
// bufOut.flush();
}
s.close();
ss.close();
}
}
TCP使用Demo4,上傳文本:
import java.io.*;
import java.net.*;
class TextClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket("192.168.1.254", 10006);
BufferedReader bufr = new BufferedReader(new FileReader("IPDemo.java"));
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
String line = null;
while ((line = bufr.readLine()) != null) {
out.println(line);
}
s.shutdownOutput();// 關(guān)閉客戶端的輸出流。相當(dāng)于給流中加入一個結(jié)束標(biāo)記-1.
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = bufIn.readLine();
System.out.println(str);
bufr.close();
s.close();
}
}
class TextServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10006);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "....connected");
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(new FileWriter("server.txt"), true);
String line = null;
while ((line = bufIn.readLine()) != null) {
// if("over".equals(line))
// break;
out.println(line);
}
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
pw.println("上傳成功");
out.close();
s.close();
ss.close();
}
}
TCP使用之上傳圖片
/*
* 需求:上傳圖片。
*/
/*
* 客戶端。
* 1,服務(wù)端點。
* 2,讀取客戶端已有的圖片數(shù)據(jù)。
* 3,通過socket 輸出流將數(shù)據(jù)發(fā)給服務(wù)端。
* 4,讀取服務(wù)端反饋信息。
* 5,關(guān)閉。
*/
import java.io.*;
import java.net.*;
class PicClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket("192.168.1.254", 10007);
FileInputStream fis = new FileInputStream("c:\\1.bmp");
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
out.write(buf, 0, len);
}
// 告訴服務(wù)端數(shù)據(jù)已寫完
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int num = in.read(bufIn);
System.out.println(new String(bufIn, 0, num));
fis.close();
s.close();
}
}
/*
* 服務(wù)端
*/
class PicServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10007);
Socket s = ss.accept();
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("server.bmp");
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
OutputStream out = s.getOutputStream();
out.write("上傳成功".getBytes());
fos.close();
s.close();
ss.close();
}
}
TCP之多線程上傳圖片
/*
* 需求:上傳圖片。
*/
/*
* 客戶端。
* 1,服務(wù)端點。
* 2,讀取客戶端已有的圖片數(shù)據(jù)。
* 3,通過socket 輸出流將數(shù)據(jù)發(fā)給服務(wù)端。
* 4,讀取服務(wù)端反饋信息。
* 5,關(guān)閉。
*
*/
import java.io.*;
import java.net.*;
class PicClient {
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("請選擇一個jpg格式的圖片");
return;
}
File file = new File(args[0]);
if (!(file.exists() && file.isFile())) {
System.out.println("該文件有問題,要么補存在,要么不是文件");
return;
}
if (!file.getName().endsWith(".jpg")) {
System.out.println("圖片格式錯誤,請重新選擇");
return;
}
if (file.length() > 1024 * 1024 * 5) {
System.out.println("文件過大,沒安好心");
return;
}
Socket s = new Socket("192.168.1.254", 10007);
FileInputStream fis = new FileInputStream(file);
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
out.write(buf, 0, len);
}
// 告訴服務(wù)端數(shù)據(jù)已寫完
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int num = in.read(bufIn);
System.out.println(new String(bufIn, 0, num));
fis.close();
s.close();
}
}
/*
* 服務(wù)端
*
* 這個服務(wù)端有個局限性。當(dāng)A客戶端連接上以后。被服務(wù)端獲取到。服務(wù)端執(zhí)行具體流程。 這時B客戶端連接,只有等待。
* 因為服務(wù)端還沒有處理完A客戶端的請求,還有循環(huán)回來執(zhí)行下次accept方法。所以 暫時獲取不到B客戶端對象。
* 那么為了可以讓多個客戶端同時并發(fā)訪問服務(wù)端。 那么服務(wù)端最好就是將每個客戶端封裝到一個單獨的線程中,這樣,就可以同時處理多個客戶端請求。
* 如何定義線程呢?
*
* 只要明確了每一個客戶端要在服務(wù)端執(zhí)行的代碼即可。將該代碼存入run方法中。
*/
class PicThread implements Runnable {
private Socket s;
PicThread(Socket s) {
this.s = s;
}
public void run() {
int count = 1;
String ip = s.getInetAddress().getHostAddress();
try {
System.out.println(ip + "....connected");
InputStream in = s.getInputStream();
File dir = new File("d:\\pic");
File file = new File(dir, ip + "(" + (count) + ")" + ".jpg");
while (file.exists())
file = new File(dir, ip + "(" + (count++) + ")" + ".jpg");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
OutputStream out = s.getOutputStream();
out.write("上傳成功".getBytes());
fos.close();
s.close();
} catch (Exception e) {
throw new RuntimeException(ip + "上傳失敗");
}
}
}
class PicServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10007);
while (true) {
Socket s = ss.accept();
new Thread(new PicThread(s)).start();
}
// ss.close();
}
}
TCP使用之并發(fā)登陸
/*
* 客戶端通過鍵盤錄入用戶名。 服務(wù)端對這個用戶名進行校驗。
* 如果該用戶存在,在服務(wù)端顯示xxx,已登陸。 并在客戶端顯示 xxx,歡迎光臨。
* 如果該用戶存在,在服務(wù)端顯示xxx,嘗試登陸。 并在客戶端顯示 xxx,該用戶不存在。
* 最多就登錄三次。
*/
import java.io.*;
import java.net.*;
class LoginClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket("192.168.1.254", 10008);
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
for (int x = 0; x < 3; x++) {
String line = bufr.readLine();
if (line == null)
break;
out.println(line);
String info = bufIn.readLine();
System.out.println("info:" + info);
if (info.contains("歡迎"))
break;
}
bufr.close();
s.close();
}
}
class UserThread implements Runnable {
private Socket s;
UserThread(Socket s) {
this.s = s;
}
public void run() {
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "....connected");
try {
for (int x = 0; x < 3; x++) {
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String name = bufIn.readLine();
if (name == null)
break;
BufferedReader bufr = new BufferedReader(new FileReader("user.txt"));
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
String line = null;
boolean flag = false;
while ((line = bufr.readLine()) != null) {
if (line.equals(name)) {
flag = true;
break;
}
}
if (flag) {
System.out.println(name + ",已登錄");
out.println(name + ",歡迎光臨");
break;
} else {
System.out.println(name + ",嘗試登錄");
out.println(name + ",用戶名不存在");
}
}
s.close();
} catch (Exception e) {
throw new RuntimeException(ip + "校驗失敗");
}
}
}
class LoginServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10008);
while (true) {
Socket s = ss.accept();
new Thread(new UserThread(s)).start();
}
}
}