① java tcp通信 gui界面
1.類socket(客服端) Socket(String host,
int port)
2.類 ServerSocket(服務端) ServerSocket(int port) 寫一個循環語句裡面使用accept() 接受客服端連接。
3.也就是一專個發數據屬時,一個收數據。InputStream/outputStream(getInputStream() getOutputStream())
自己看API編寫就行了。
② JAVA TCP通信,客戶端給伺服器傳送JAVA對象通信出錯了,求各位大神指教
在java中用socket傳輸對象的時候,底層是把java對象序列化,然後以二進制數據進行傳輸的。socket的服務端和客戶端都需要有這個對象的聲明,比如客戶端發送的是com.client.MsgPackage對象,那麼這個對象的class文件必須在服務端的classpath中。否則就會是接收方接收了tcp的數據包,但是無法還原成對象。
底層要能把對象序列化,這個對象要實現一個可序列化的介面:java.io.Serializable。
類通過實現 java.io.Serializable
介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。序列化介面沒有方法或欄位,僅用於標識可序列化的語義。
writeObject 方法負責寫入特定類的對象的狀態,以便相應的 readObject 方法可以恢復它。通過調用
out.defaultWriteObject 可以調用保存 Object 的欄位的默認機制。該方法本身不需要涉及屬於其超類或子類的狀態。通過使用
writeObject 方法或使用 DataOutput 支持的用於基本數據類型的方法將各個欄位寫入 ObjectOutputStream,狀態可以被保存。
readObject 方法負責從流中讀取並恢復類欄位。它可以調用 in.defaultReadObject
來調用默認機制,以恢復對象的非靜態和非瞬態欄位。defaultReadObject
方法使用流中的信息來分配流中通過當前對象中相應指定欄位保存的對象的欄位。這用於處理類演化後需要添加新欄位的情形。該方法本身不需要涉及屬於其超類或子類的狀態。通過使用
writeObject 方法或使用 DataOutput 支持的用於基本數據類型的方法將各個欄位寫入 ObjectOutputStream,狀態可以被保存。
③ TCP/IP協議 怎麼用JAVA發送和接收二進制數據 要具體實例
1.TCP/IP協議要求信息必須在塊(chunk)中發送和接收,而塊的長度必須是8位的倍數,因此,我們可以認為TCP/IP協議中傳輸的信息是位元組序列。如何發送和解析信息需要一定的應用程序協議。
2.信息編碼:
首先是Java里對基本整型的處理,發送時,要注意:1)每種數據類型的位元組個數;2)這些位元組的發送順序是怎樣的?(little-endian還是
big-endian);3)所傳輸的數值是有符號的(signed)還是無符號的(unsigned)。具體編碼時採用位操作(移位和屏蔽)就可以了。
具體在Java里,可以採用DataOutputStream類和ByteArrayOutputStream來實現。恢復時可以採用
DataInputStream類和ByteArrayInputStream類。
其次,字元串和文本,在一組符號與一組整數之間的映射稱為編碼字元集(coded character
set)。發送者與接收者必須在符號與整數的映射方式上達成共識,才能使用文本信息進行通信,最簡單的方法就是定義一個標准字元集。具體編碼時採用
String的getBytes()方法。
最後,位操作。如果設置一個特定的設為1,先設置好掩碼(mask),之後用或操作;要清空特定一位,用與操作。
3.成幀與解析
成幀(framing)技術解決了接收端如何定位消息的首位位置的問題。
如果接收者試圖從套接字中讀取比消息本身更多的位元組,將可能發生以下兩種情況之一:如果信道中沒有其他消息,接收者將阻塞等待,同時無法處理接收
到的消息;如果發送者也在等待接收端的響應消息,則會形成死鎖(dealock);另一方面,如果信道中還有其他消息,則接收者會將後面消息的一部分甚至
全部讀到第一條消息中去,這將產生一些協議錯誤。因此,在使用TCP套接字時,成幀就是一個非常重要的考慮因素。
有兩個技術:
1.基於定界符(Delimiter-based):消息的結束由一個唯一的標記(unique
marker)指出,即發送者在傳輸完數據後顯式添加的一個特殊位元組序列。這個特殊標記不能在傳輸的數據中出現。幸運的是,填充(stuffing)技術
能夠對消息中出現的定界符進行修改,從而使接收者不將其識別為定界符。在接收者掃描定界符時,還能識別出修改過的數據,並在輸出消息中對其進行還原,從而
使其與原始消息一致。
2.顯式長度(Explicit length):在變長欄位或消息前附加一個固定大小的欄位,用來指示該欄位或消息中包含了多少位元組。這種方法要確定消息長度的上限,以確定保存這個長度需要的位元組數。
介面:
Java代碼 import java.io.IOException; import java.io.OutputStream; public interface Framer { void frameMsg(byte [] message,OutputStream out) throws IOException; byte [] nextMsg() throws IOException; }
定界符的方式:
Java代碼 import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class DelimFramer implements Framer { private InputStream in;//data source; private static final byte DELIMTER=(byte)'\n';//message delimiter public DelimFramer(InputStream in){ this.in=in; } @Override public void frameMsg(byte[] message, OutputStream out) throws IOException { //ensure that the message dose not contain the delimiter for(byte b:message){ if(b==DELIMTER) throw new IOException("Message contains delimiter"); } out.write(message); out.write(DELIMTER); out.flush(); } @Override public byte[] nextMsg() throws IOException { ByteArrayOutputStream messageBuffer=new ByteArrayOutputStream(); int nextByte; while((nextByte=in.read())!=DELIMTER){ if(nextByte==-1){//end of stream? if(messageBuffer.size()==0){ return null; }else{ throw new EOFException("Non-empty message without delimiter"); } } messageBuffer.write(nextByte); } return messageBuffer.toByteArray(); } }
顯式長度方法:
Java代碼 import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class LengthFramer implements Framer { public static final int MAXMESSAGELENGTH=65535; public static final int BYTEMASK=0xff; public static final int SHOTMASK=0xffff; public static final int BYTESHIFT=8; private DataInputStream in;// wrapper for data I/O public LengthFramer(InputStream in) throws IOException{ this.in=new DataInputStream(in); } @Override public void frameMsg(byte[] message, OutputStream out) throws IOException { if(message.length>MAXMESSAGELENGTH){ throw new IOException("message too long"); } //write length prefix out.write((message.length>>BYTEMASK)&BYTEMASK); out.write(message.length&BYTEMASK); //write message out.write(message); out.flush(); } @Override public byte[] nextMsg() throws IOException { int length; try{ length=in.readUnsignedShort(); }catch(EOFException e){ //no (or 1 byte) message; return null; } //0<=length<=65535; byte [] msg=new byte[length]; in.readFully(msg);//if exception,it's a framing error; return msg; } }
④ TCP和UDP通信有什麼區別 如何分別用java實現
TCP是面向連來接,自UDP面向非連接,資料不復制,在這里簡單說下:
TCP建立連接時需要傳說的三次握手,服務端與客戶端需要確認對方身份而已,建立好連接後,就開始傳遞消息,直到有一方斷開連接位置。 就好比兩個人打電話,要先通了才能說話。
UDP只是數據報發送,它的優點速度快,並非要向TCP那樣麻煩建立,它只負責將信息發出,但是並不確保信息的准確完整性等,就好比發簡訊,簡訊是出去了,但是中間是否有問題,是否對方手機能收到就不管了。
在java中想要實現上述兩種協議通信,可採用socket建立連接,socket可以理解為碼頭,其實是套接字,這里簡單說下,就好比兩個城市運輸貨物,通過碼頭走貨一樣。至於如何通過socket建立兩個連接,網上資料多的是,在這里不復制例子了。
⑤ 用java編寫一個能進行簡單TCP/IP通信的C/S程序
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer
{
public static void main(String[] args) throws Exception
{
// 創建伺服器端的socket對象
ServerSocket ss = new ServerSocket(5000);
// 監聽連接
Socket socket = ss.accept();
// 直到連接建立好之後代碼才會往下執行
System.out.println("Connected Successfully!");
}
}
import java.net.Socket;
public class TcpClient
{
public static void main(String[] args) throws Exception
{
Socket socket = new Socket("127.0.0.1", 5000);
}
}
⑥ Java TCP socket通信,如何實現發送十六進制值,並在數據接收窗口中顯示這些數據對應的字元串,非常感謝!
我自己的電腦上有一段源代碼,就是基於TCP聊天小代碼,能進行相互之間的消息接受。我的代碼是直接傳輸字元串的,不是16進制滴。嗯,也貼出來看看吧!
運行伺服器,c1,c2就可以了,c1與c2可進行通信。
Client.java
import java.net.*;
public class Client{
static byte num=1;
private int portNum;
public Client(int portnum){
this.portNum=portnum;
System.out.println("您是第"+num+"位客服端");
num++;
}
public void sentMessage(String me){
//都是向伺服器發信息埠號1999
try{
DatagramSocket ds=new DatagramSocket();
DatagramPacket dp=new DatagramPacket(me.getBytes(),me.length(),InetAddress.getByName("127.0.0.1"),1999);
ds.send(dp);
ds.close();
}catch(Exception e){
e.printStackTrace();
}
}
public String receiveMessage(){
String str="";
try{
DatagramSocket ds=new DatagramSocket(this.portNum);//表示哦自己的接收埠號是1999
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,1024);
ds.receive(dp);
str=new String(dp.getData(),0,dp.getLength());
ds.close();
}catch(Exception e){
e.printStackTrace();
}
return str;
}
}
c1.java
import java.util.*;
public class c1 implements Runnable{
Client cl;
boolean goon=true;
Scanner sc=new Scanner(System.in);
public c1(){
cl=new Client(2000);
System.out.println("這里是2000客戶端\n你可以發送信息。請輸入要發送的信息。out退出");
new Thread(this).start();
while(this.goon==true){
say();
}
if(goon==false){
System.exit(0);
}
}
public static void main(String[] args){
new c1();
}
public void say(){
String mess=sc.nextLine();
System.out.println("是否發送y/n");
String key=sc.nextLine();
if(key.equals("y")){
System.out.println("信息信息發送中……");
try{
cl.sentMessage(mess);
}catch(Exception e){
e.printStackTrace();
}
}
else if(key.equals("out")){
goon=false;
}
}
public void run(){
while(this.goon==true){
String sst="";
try{
sst=cl.receiveMessage();
}catch(Exception e){
e.printStackTrace();
}
if(sst.length()>0){
System.out.println(sst);
}
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("程序結束!");
}
}
c2.java
import java.util.*;
public class c2 implements Runnable{
Client cl;
boolean goon=true;
Scanner sc=new Scanner(System.in);
public c2(){
cl=new Client(2001);
System.out.println("這里是2001客戶端\n你可以發送信息。請輸入要發送的信息。out退出");
new Thread(this).start();
while(goon==true){
say();
}
if(goon==false){
System.exit(0);
}
}
public static void main(String[] args){
new c2();
}
public void say(){
String mess=sc.nextLine();
System.out.println("是否發送y/n");
String key=sc.nextLine();
if(key.equals("y")){
System.out.println("信息信息發送中……");
try{
cl.sentMessage(mess);
}catch(Exception e){
e.printStackTrace();
}
}
else if(key.equals("out")){
this.goon=false;
}
}
public void run(){
while(this.goon==true){
String sst="";
try{
sst=cl.receiveMessage();
}catch(Exception e){
e.printStackTrace();
}
if(sst.length()>0){
System.out.println(sst);
}
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("聊天關閉!");
}
}
Server.java
import java.net.*;
import java.util.*;
public class Server implements Runnable{
private String message;
boolean work=true;
byte tm=10;
String[] clomessage={"信息:正在斷開網路連接.",".",".\n","信息:設置保存中……","","","完成\n","信息:歡迎下次使用\n","信息:完成\n","Goodbye!"};
public Server(){
new Thread(this).start();
System.out.println("本程序為服務端Server");
Scanner sc=new Scanner(System.in);
System.out.println("輸入命令out關閉伺服器");
String clo=sc.nextLine();
if(clo.equals("out")){
System.out.println("正在關閉伺服器……");
setwork(false);
System.exit(0);
}
}
public static void main(String[] args){
new Server();
}
public void setwork(boolean bo)
{
this.work=bo;
}
public void setMessage(String str){
this.message=str;
}
public String getMessage(){
return this.message;
}
public void sentMessage(){
String mes=this.getMessage();
try{
DatagramSocket ds=new DatagramSocket();
DatagramPacket dp=new DatagramPacket(mes.getBytes(),mes.length(),InetAddress.getByName("127.0.0.1"),2000);
DatagramPacket dp2=new DatagramPacket(mes.getBytes(),mes.length(),InetAddress.getByName("127.0.0.1"),2001);
ds.send(dp);
ds.send(dp2);
ds.close();
System.out.println("信息發送至:127.0.0.1:2000 & 127.0.0.1:2001");
this.setMessage("");
}catch(Exception e){
e.printStackTrace();
}
}
public void receiveMessage() throws Exception{
try{
DatagramSocket ds=new DatagramSocket(1999);//表示哦自己的接收埠號是1999
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,1024);
ds.receive(dp);
String str=new String(dp.getData(),0,dp.getLength());
if(str.length()>0){
this.setMessage(str);
System.out.println("信息:Server從"+dp.getAddress().getHostAddress()+"主機(埠號:"+dp.getPort()+")收到信息:"+this.getMessage());
}
ds.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void run(){
while(tm>0){
if(work==false){
tm--;
System.out.print(clomessage[9-tm]);
}
try{
receiveMessage();//時刻接受信息
}catch(Exception e){
e.printStackTrace();
}
if(this.getMessage().length()>0){//如果接收到信息則發送信息
try{
sentMessage();
}catch(Exception e){
e.printStackTrace();
}
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}
呵呵,請指教啊!
⑦ 在Java中實現TCP協議編程中怎麼傳
在Java中實現TCP協議編程
ServerSocket:編寫TCP網路服務程序,首先要用到java.net.ServerSocket類用以創建伺服器Socket
構造方法:
ServerSocket(intport):創建綁定到特定埠的伺服器套接字
ServerSocket(intport,intbacklog):利用指定的backlog(伺服器忙時保持連接請求的等待客戶數量),創建伺服器套接字並將其綁定到指定的本地埠號。
ServerSocket(intport,intbacklog,InetAddressbindAddr):使用指定的埠、偵聽backlog和要綁定到的本地IP地址創建伺服器。
Socket:客戶端要與伺服器建立連接,必須先創建一個Socket對象
常用構造方法
Socket(Stringhost,intport):創建一個流套接字並將其連接到指定主機上的指定埠號。
Socket(InetAddressaddress,intport):創建一個流套接字並將其連接到指定IP地址的指定埠號。
伺服器端程序調用ServerSocket類中的accept()方法等待客戶端的連接請求,一旦accept()接收了客戶端連接請求,該方法返回一個與該客戶端建立了專線連接的Socket對象,不用程序去創建這個Socket對象。建立了連接的兩個Socket是以IO流的方式進行數據交換的,Java提供了Socket類中的getInputStream()返回Socket的輸入流對象,getOutputStream()返回Socket的輸出流對象。
TCP伺服器與TCP客戶端間的數據的接受圖示:
用TCP實現伺服器與客戶端的「聊天」:
實例代碼:
客戶端:
packagecom.hbsi.net;
importjava.net.Socket;
importjava.io.*;
publicclassTcpClient{
publicstaticvoidmain(String[]args)throwsException{
//1.建立tcp客戶端socket,要確定要連接的伺服器ip,port
Sockets=newSocket("192.168.49.87",9009);
//獲取鍵盤錄入
BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));
//2.通過建立的socket,獲取輸出流對象
//數據輸出給伺服器端
OutputStreamout=s.getOutputStream();
BufferedWriterbwout=newBufferedWriter(newOutputStreamWriter(out));
//獲取伺服器端返回的數據
//讀取伺服器端發過來的信息InputStreamReader()
BufferedReaderbrin=newBufferedReader(newInputStreamReader(
s.getInputStream()));
Stringline=null;
while((line=br.readLine())!=null){
if(line.equals("over"))
break;
bwout.write(line);
bwout.newLine();
bwout.flush();
Stringstr=brin.readLine();
System.out.println("server:"+str);
}
br.close();
s.close();
}
}
伺服器端:
packagecom.hbsi.net;
importjava.io.BufferedReader;
importjava.io.BufferedWriter;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
importjava.net.ServerSocket;
importjava.net.Socket;
publicclassTcpServer{
publicstaticvoidmain(String[]args)throwsException{
//1.建立伺服器socket
ServerSocketss=newServerSocket(9009);
//2.調用accept()
Sockets=ss.accept();
System.out.println(s.getInetAddress().getHostAddress()
+"...connection");
//讀取客戶的信息的輸入流
InputStreamin=s.getInputStream();
BufferedReaderbrin=newBufferedReader(newInputStreamReader(in));
//向客戶端發送信息輸出流,服務端向客戶端返回信息OutputStreamWriter()
BufferedWriterbrout=newBufferedWriter(newOutputStreamWriter(
s.getOutputStream())); Stringline=null;
while((line=brin.readLine())!=null){
System.out.println("client:"+line);
brout.write(line.toUpperCase());//伺服器端收到信息後,將信息轉為大寫返回給客戶端toUpperCase()
brout.newLine();
brout.flush();
}
s.close();
ss.close();
}
}