當前位置:首頁 » 編程軟體 » javasocket編程實例

javasocket編程實例

發布時間: 2023-09-08 06:47:58

❶ 用java實現一個人和幾個不同的人私聊,用Socket實現

package API_Day09;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

/**
* 控制台聊天程序
* 客戶端應用程序
* @author Jacob
*
*/
public class chatClient
{
//客戶端用於與服務端連接的Socket
private Socket clientSocket;

/**
* 構造方法,客戶端初始化
*/
public chatClient()
{
try
{
/*
* socket(String host, int port)
* 地址: IP地址,用來定位網路上的計算機
* 埠: 用來找到遠端計算機上用來連接的服務端應用程序
*/
clientSocket = new Socket("localhost",12580);

}
catch (Exception e)
{
e.printStackTrace();
}
}

/**
* 客戶端昵稱驗證方法
* @param 為Scanner
*/
private void inputNickName(Scanner scan) throws Exception
{
String nickName = null;
//創建輸出流
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(clientSocket.getOutputStream(),
"UTF-8"),true);
//創建輸入流
BufferedReader br = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream(),"UTF-8"));

while(true)
{
System.out.println("請創建您的昵稱:");
nickName = scan.nextLine();
if (nickName.trim().equals(""))
{
System.out.println("昵稱不得為空");
}
else
{
pw.println(nickName);
String pass = br.readLine();
if(pass!=null&&!pass.equals("OK"))
{
System.out.println("昵稱已經被佔用,請更換!");
}
else
{
System.out.println("你好!"+nickName+"可以開始聊天了");
break;
}
}
}
}

/*
* 客戶端啟動的方法
*/
public void start()
{
try
{
/*
* 創建Scanner,讀取用戶輸入內容
* 目的是設置客戶端的昵稱
*/
Scanner scanner = new Scanner(System.in);
inputNickName(scanner);

/*
* 將用於接收伺服器端發送過來的信息的線程啟動
*/
Runnable run = new GetServerMsgHandler();
Thread t = new Thread(run);
t.start();

/*
* 建立輸出流,給服務端發信息
*/
OutputStream os = clientSocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
PrintWriter pw = new PrintWriter(osw,true);

while(true)
{
pw.println(scanner.nextLine());
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(clientSocket !=null)
{
try
{
clientSocket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}

/**
* 該線程體用來循環讀取服務端發送過來的信息
* 並輸出到客戶端的控制台
* @param args
*/
class GetServerMsgHandler implements Runnable
{
@Override
public void run()
{
try
{
InputStream is = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String msgString = null;
while((msgString = br.readLine())!= null)
{
System.out.println("服務端提示:"+ msgString);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

public static void main(String[] args)
{
chatClient client = new chatClient();
client.start();
}
}
package API_Day09;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* 控制台聊天程序
* 服務端應用程序
* @author Jacob
*
*/
public class chatServer
{
/**
* ServerSocket 是運行在服務端的Socket
* 用來監聽埠,等待客戶端的連接,
* 一旦連接成功就會返回與該客戶端通信的Socket
*/
private ServerSocket serverSocket;

/**
* 創建線程池來管理客戶端的連接線程
* 避免系統資源過度浪費
*/
private ExecutorService threadPool;

/**
* 該屬性用來存放客戶端之間私聊的信息
*/
private Map<String,PrintWriter> allOut;

/**
* 構造方法,服務端初始化
*/
public chatServer()
{
try
{
/*
* 創建ServerSocket,並申請服務埠
* 將來客戶端就是通過該埠連接服務端程序的
*/
serverSocket = new ServerSocket(12580);

/*
* 初始化Map集合,存放客戶端信息
*/
allOut = new HashMap<String, PrintWriter>();

/*
* 初始化線程池,設置線程的數量
*/
threadPool = Executors.newFixedThreadPool(10);

/*
* 初始化用來存放客戶端輸出流的集合,
* 每當一個客戶端連接,就會將該客戶端的輸出流存入該集合;
* 每當一個客戶端斷開連接,就會將集合中該客戶端的輸出流刪除;
* 每當轉發一條信息,就要遍歷集合中的所有輸出流(元素)
* 因此轉發的頻率高於客戶端登入登出的頻率,
* 還是應該使用ArrayList來存儲元素,僅限群聊,私聊不行
* allOut = new ArrayList<PrintWriter>();
*/
}
catch (Exception e)
{
e.printStackTrace();
}
}

/*
* 將客戶端的信息以Map形式存入集合中
*/
private void addOut(String key,PrintWriter value)
{
synchronized(this)
{
allOut.put(key, value);
}
}

/*
* 將給定的輸出流從共享集合中刪除
* 參數為客戶端nickName,作為Map的key鍵
*/
private synchronized void removeOut(String key)
{
allOut.remove(key);
System.out.println("當前在線人數為:"+ allOut.size());
}

/*
* 將給定的消息轉發給所有客戶端
*/
private synchronized void sendMsgToAll(String message)
{
for(PrintWriter out: allOut.values())
{
out.println(message);
System.out.println("當前在線人數為:"+ allOut.size());
}
}

/*
* 將給定的消息轉發給私聊的客戶端
*/
private synchronized void sendMsgToPrivate(String nickname,String message)
{
PrintWriter pw = allOut.get(nickname); //將對應客戶端的聊天信息取出作為私聊內容發送出去
if(pw!=null)
{
pw.println(message);
System.out.println("當前在線私聊人數為:"+ allOut.size());
}
}

/**
* 服務端啟動的方法
*/
public void start()
{
try
{
while(true)
{
/*
* 監聽10086埠
*/
System.out.println("等待客戶端連接... ... ");
/*
* Socket accept() 這是一個阻塞方法,會一直在10086埠進行監聽
* 直到一個客戶端連接上,此時該方法會將與這個客戶端進行通信的Socket返回
*/
Socket socket = serverSocket.accept();
System.out.println("客戶端連接成功! ");

/*
* 啟動一個線程,由線程來處理客戶端的請求,這樣可以再次監聽
* 下一個客戶端的連接了
*/
Runnable run = new GetClientMsgHandler(socket);
threadPool.execute(run); //通過線程池來分配線程
}
}
catch(Exception e)
{
e.printStackTrace();
}
}

/**
* 該線程體用來處理給定的某一個客戶端的消息,循環接收客戶端發送
* 的每一個字元串,並輸出到控制台
* @author Jacob
*
*/
class GetClientMsgHandler implements Runnable
{
/*
* 該屬性是當前線程處理的具體的客戶端的Socket
* @see java.lang.Runnable#run()
*/
private Socket socket;

/*
* 獲取客戶端的地址信息
* private String hostIP;
*/

/*
* 獲取客戶端的昵稱
*/
private String nickName;

/*
* 創建構造方法
*/
public GetClientMsgHandler(Socket socket)
{
this.socket = socket;

/*
* 獲取遠端客戶的Ip地址信息
* 保存客戶端的IP地址字元串
* InetAddress address = socket.getInetAddress();
* hostIP = address.getHostAddress();
*/
}

/*
* 創建內部類來獲取昵稱
*/
private String getNickName() throws Exception
{
try
{
//服務端的輸入流讀取客戶端發送來的昵稱輸出流
InputStream iin = socket.getInputStream();
InputStreamReader isr =
new InputStreamReader(iin,"UTF-8");
BufferedReader bReader = new BufferedReader(isr);
//服務端將昵稱驗證結果通過自身的輸出流發送給客戶端
OutputStream out = socket.getOutputStream();
OutputStreamWriter iosw =
new OutputStreamWriter(out,"UTF-8");
PrintWriter ipw = new PrintWriter(iosw,true);
//讀取客戶端發來的昵稱
String nameString = bReader.readLine();
while(true)
{
if(nameString.trim().length()==0)
{
ipw.println("FAIL");
}
if(allOut.containsKey(nameString))
{
ipw.println("FAIL");
}
else
{
ipw.println("OK");
return nameString;
}
nameString = bReader.readLine();
}
}
catch(Exception e)
{
throw e;
}
}

@Override
public void run()
{
PrintWriter pw = null;
try
{
/*
* 通過客戶端的Socket獲取客戶端的輸出流
* 用來將消息發送給客戶端
*/
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
pw = new PrintWriter(osw,true);

/*
* 將客戶昵稱和其所說的話作為元素存入共享集合HashMap中
*/
nickName = getNickName();
addOut(nickName, pw);
Thread.sleep(100);

/*
* 服務端通知所有客戶端,某用戶登錄
*/
sendMsgToAll("[系統通知]:歡迎**"+nickName+"**登陸聊天室!");

/*
* 通過客戶端的Socket獲取輸入流
* 讀取客戶端發送來的信息
*/
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String msgString = null;

while((msgString = br.readLine())!=null)
{
//驗證是否是私聊
if(msgString.startsWith("@"))
{
/*
* 私聊格式:@昵稱:內容
*/
int index = msgString.indexOf(":");
if(index >=0)
{
//獲取昵稱
String name = msgString.substring(1,index);
String info = msgString.substring(index+1,msgString.length());
info = nickName + "對你說:"+ info;
//將私聊信息發送出去
sendMsgToPrivate(name, info);
//服務端不在廣播私聊的信息
continue;
}
}
/*
* 遍歷所有輸出流,將該客戶端發送的信息轉發給所有客戶端
*/
System.out.println(nickName+"說:"+ msgString);
sendMsgToAll(nickName+"說:"+ msgString);
}
}
catch (Exception e)
{
/*
* 因為Win系統用戶的客戶端斷開連接後,br.readLine()方法讀取
* 不到信息就會拋出異常,而Linux系統會持續發送null;
* 因此這里就不在將捕獲的異常拋出了。
*/
}
finally
{
/*
* 當執行到此處時,說明客戶端已經與服務端斷開連接
* 則將該客戶端存在共享集合中的輸出流刪除
*/
removeOut(nickName);
/*
* 通知所有客戶端,某某客戶已經下線
*/
sendMsgToAll("[系統通知]:"+nickName + "已經下線了。");

/*
* 關閉socket,則通過Socket獲取的輸入輸出流也一同關閉了
*/
if(socket!=null)
{
try
{
socket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
}

public static void main(String[] args)
{
chatServer server = new chatServer();
server.start();
}
}
我的作業,供你參考

❷ java編程中,Socket通信是怎麼實現的

java編程對於Socket之間的通信過程如下:

服務端往Socket的輸出流裡面寫東西,客戶端就可以通過Socket的輸入流讀取對應的內容。Socket與Socket之間是雙向連通的,所以客戶端也可以往對應的Socket輸出流裡面寫東西,然後服務端對應的Socket的輸入流就可以讀出對應的內容。下面來看一些服務端與客戶端通信的例子:

publicclassServer{

publicstaticvoidmain(Stringargs[])throwsIOException{
//為了簡單起見,所有的異常信息都往外拋
intport=8899;
//定義一個ServerSocket監聽在埠8899上
ServerSocketserver=newServerSocket(port);
//server嘗試接收其他Socket的連接請求,server的accept方法是阻塞式的
Socketsocket=server.accept();
//跟客戶端建立好連接之後,我們就可以獲取socket的InputStream,並從中讀取客戶端發過來的信息了。
Readerreader=newInputStreamReader(socket.getInputStream());
charchars[]=newchar[64];
intlen;
StringBuildersb=newStringBuilder();
while((len=reader.read(chars))!=-1){
sb.append(newString(chars,0,len));
}
System.out.println("fromclient:"+sb);
reader.close();
socket.close();
server.close();
}

}
客戶端代碼
Java代碼publicclassClient{

publicstaticvoidmain(Stringargs[])throwsException{
//為了簡單起見,所有的異常都直接往外拋
Stringhost="127.0.0.1";//要連接的服務端IP地址
intport=8899;//要連接的服務端對應的監聽埠
//與服務端建立連接
Socketclient=newSocket(host,port);
//建立連接後就可以往服務端寫數據了
Writerwriter=newOutputStreamWriter(client.getOutputStream());
writer.write("HelloServer.");
writer.flush();//寫完後要記得flush
writer.close();
client.close();
}

}

❸ 用JAVA編寫一個socket通信程序。

importjava.io.BufferedReader;
importjava.io.InputStreamReader;
importjava.net.ServerSocket;
importjava.net.Socket;

publicclassServer{

publicstaticvoidmain(String[]args){
ServerSocketss;
Sockets;
try{
ss=newServerSocket(8888);
s=ss.accept();
InputStreamReaderisr=newInputStreamReader(s.getInputStream());
BufferedReaderbr=newBufferedReader(isr);

System.out.println(br.readLine());
br.close();
isr.close();

}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}


}

}

importjava.io.PrintWriter;
importjava.net.Socket;


publicclassClient{

publicstaticvoidmain(String[]args){

try{
Sockets=newSocket("127.0.0.1",8888);

PrintWriterpw=newPrintWriter(s.getOutputStream());
pw.write("helloserver");
pw.flush();

pw.close();
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}

}

}

❹ 瘋狂Java講義:使用Socket進行通信[2]

程序清單 codes/ / /Client java

public class Client

{

public static void main(String[] args)

throws IOException

{

Socket socket = new Socket( )

//將Socket對應的輸入流包裝成BufferedReader

BufferedReader br = new BufferedReader(

new InputStreamReader(socket getInputStream()))

//進行普通IO操作

String line = br readLine()

System out println( 來自伺服器的數據 + line)

//關閉輸入流 socket

br close()

socket close()

}

}

上面程序中粗體字代碼是使用ServerSocket和Socket建立網路連接的代碼 斜體字代碼是通過Socket獲取輸入流 輸出流進行通信的代碼 通過程序不難看出 一旦使用ServerSocket Socket建立網路連接之後 程序通過網路通信與普通IO並沒有太大的區別

先運行上面程序中的Server類 將看到伺服器一直處於等待狀態 因為伺服器使用了死循環來接受來自客戶端的請求 再運行Client類 將可看到程序輸出 來自伺服器的數據 您好 您收到了伺服器的新年祝福! 這表明客戶端和伺服器端通信成功

上面程序為了突出通過ServerSocket和Socket建立連接 並通過底層IO流進行通信的主題 程序沒有進行異常處理 也沒有使用finally塊來關閉資源

實際應用中 程序可能不想讓執行網路連接 讀取伺服器數據的進程一直阻塞 而是希望當網路連接 讀取操作超過合理時間之後 系統自動認為該操作失敗 這個合理時間就是超時時長 Socket對象提供了一個setSoTimeout(int timeout)來設置超時時長 如下的代碼片段所示

Socket s = new Socket( )

//設置 秒之後即認為超時

s setSoTimeout( )

當我們為Socket對象指定了超時時長之後 如果在使用Socket進行讀 寫操作完成之前已經超出了該時間限制 那麼這些方法就會拋出SocketTimeoutException異常 程序可以對該異常進行捕捉 並進行適當處理 如下代碼所示

try

{

//使用Scanner來讀取網路輸入流中的數據

Scanner scan = new Scanner(s getInputStream())

//讀取一行字元

String line = scan nextLine()

}

//捕捉SocketTimeoutException異常

catch(SocketTimeoutException ex)

{

//對異常進行處理

}

假設程序需要為Socket連接伺服器時指定超時時長 即經過指定時間後 如果該Socket還未連接到遠程伺服器 則系統認為該Socket連接超時 但Socket的所有構造器里都沒有提供指定超時時長的參數 所以程序應該先創建一個無連接的Socket 再調用Socket的connect()方法來連接遠程伺服器 而connect方法就可以接受一個超時時長參數 如下代碼所示

//創建一個無連接的Socket

Socket s = new Socket()

//讓該Socket連接到遠程伺服器 如果經過 秒還沒有連接到 則認為連接超時

s connconnect(new InetAddress(host port) )

返回目錄 瘋狂Java講義

編輯推薦

Java程序性能優化 讓你的Java程序更快 更穩定

新手學Java 編程

Java程序設計培訓視頻教程

lishixin/Article/program/Java/hx/201311/27265

❺ 大家給我寫一個java socket的簡單例子

客戶端的。
String ip = "172.31.1.130";
ip = "127.0.0.1";
int port = 10004;
try {
Socket socket = new Socket(ip, port);
socket.setSoTimeout(5539900);
java.io.OutputStream out = socket.getOutputStream();

byte[] date = "hello world".getBytes();
out.write(data);
out.flush();

socket.shutdownOutput();

byte[] buffer = new byte[1024];
int len = -1;
java.io.FileOutputStream fout = new java.io.FileOutputStream(
"d:/response.xml");
java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();

java.io.InputStream in = socket.getInputStream();

while ((len = in.read(buffer, 0, buffer.length)) > 0) {
bout.write(buffer, 0, len);
}
in.close();
bout.flush();
bout.close();

byte[] rdata = bout.toByteArray();
// System.out.println("leen = " + (rdata.length - 32));
System.out.println(new String(rdata));

fout.write(rdata);
fout.flush();
fout.close();
socket.close();

} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

伺服器端的

ServerSocket ss = new ServerSocket(8090);
Socket socket=null;
BufferedReader in;
PrintWriter out;

while (true)
{
socket = ss.accept();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true);
String line = in.readLine();
out.println("you input is :" + line);
out.close();
in.close();
socket.close();
}

熱點內容
wifi無法上網怎麼配置網路 發布:2024-11-19 20:25:38 瀏覽:437
我的世界網易手機好玩的pvp伺服器 發布:2024-11-19 20:09:29 瀏覽:331
安卓手機微信怎麼改號 發布:2024-11-19 19:56:13 瀏覽:91
python的字元串輸出 發布:2024-11-19 19:48:41 瀏覽:630
android的簽名 發布:2024-11-19 19:47:10 瀏覽:489
padavan內核修改編譯 發布:2024-11-19 19:46:53 瀏覽:219
apex正在載入並編譯著色器閃退 發布:2024-11-19 19:40:13 瀏覽:282
android導圖 發布:2024-11-19 19:37:48 瀏覽:975
雲伺服器慢慢變卡 發布:2024-11-19 19:32:33 瀏覽:664
如何找到伺服器參數 發布:2024-11-19 19:19:33 瀏覽:678