1. Qt網路編程 伺服器異常斷開,不能檢查到網路狀態變化
自己做心跳保活。因為異常斷開不屬於qt的處理范圍,而tcp協議棧又不存在自動處理異常斷線的功能,tcp連接在不正常關閉情況下通常都會被協議棧保持存活一段時間(具體和操作系統協議棧實現和設置有關)。qt無法獲得tcp協議棧的狀態消息,也就不會做出任何反應。所謂心跳機制請參照以下網址內容:
http://ke..com/view/4372209.htm
2. 關於TCP套接字網路編程過程中的一個問題,求指點
把if (!strcmp("tiuq",recvline))改成 if (strstr("tiuq", recvline))試試看,可能是你在終端裡面敲的回車符\r也被吸收進去了,然後反轉之後變成"\rtiuq",所以strcmp比較不對,換成strstr
3. TCP/IP協議與網路編程
先搞清楚 ISO/OSI與TCP/IP的關系
1.2 TCP/IP的分層體系結構與協議棧的概念
問題1:什麼叫協議棧(Protocol Stack)?
如上圖所示,網路協議是分層的,在這種層次結構中各層有明確的分工,不同層的協議從上到下形成了一個棧結構的依賴關系,通常將其形象地稱為協議棧.問題2:為什麼協議棧簡稱TCP/IP?
如上圖所示,從該結構中可以看出,在TCP/IP的協議棧中包括很多協議(如FTP,IGMP等),但TCP和IP是該協議棧中兩個最重要的協議,所以人們常常將該協議棧簡稱TCP/IP問題3:為什麼協議棧中TCP與IP是最重要的協議?
先理解一下這4層的基本概念
------>第1層:網路介面層
功能1:發包與收包
(1)發包。它是協議棧的最底層,負責將其之上的網路層要發送出去的數據(即IP數據報)發送到其下面的物理網路
(2)收包。接收由物理網路發送到該目標機的數據幀,並抽出IP數據報交給網路層。要注意,這里所說的物理網路是指各種實際傳輸數據的區域網或廣域網等。功能2:為什麼在TCP/IP協議棧中沒有定義網路介面層呢?
(1)便於實現不同網路之間的互聯。
實現不同網路的互聯是TCP/IP要解決的最主要問題。不同的網路盡管其數據傳輸介質,數據傳輸速率等有很大的差異,但都可以實現網路內數據的傳輸,當然也就可以進行TCP/IP協議棧中網路層IP數據報的傳輸。這樣TCP/IP就可以將重點放在網路之間的互聯上,而不用去糾纏各種物理網路的具體實現細節,這樣就非常巧妙地解決了不同類型物理網路的互聯問題。這也是TCP/IP得以廣泛應用的一個重要原因
(2)為將來物理網路的發展留下了廣闊的空間------>第2層:網際層(也稱互聯網路層)
功能:把源主機上的分組(在網際層傳輸的數據單位叫IP數據報,也稱為IP分組)根據需要發送到互聯網中的任何一台目標主機上.(關於怎樣得到目標主機的IP地址,詳見第3章中的ARP)什麼叫路由選擇?
在一個由很多網路組成的互聯網中,一台主機(即源主機)與不在同一個網路中的另一台主機(目標主機)通信時,可能有多條通路相連,網際層的一個重要功能就是要在這些通路中做出選擇,這就是所謂的路由選擇功能.它是網際層一個非常重要的功能------>第3層:傳輸層
------>第4層:應用層結論:
為什麼IP層非常重要?
IP層重點面向同外界打交道,比如你在廣州,我在北京,IP層就能通過路由選擇一條道路,以及到站後,就開始用ARP廣播,你們誰是這個MAC地址的主人,聽到了請回復,這時對方的IP層收包了,與自己MAC地址(全球唯一地址)一樣,就開始解包(當然上層要有相應處理軟體程序)
為什麼TCP層非常重要?
TCP層重點面向同內部打交道,我的任務是要檢查你發到我電腦裡面的這個數據是不是正確的。
在IP層提供的是一種"盡力而為"的數據報傳輸服務,它不能保證數據總是可靠地從源主機傳輸到目標主機,為什麼TCP能保證數據傳輸正確,因為它每發送一個數據都會要效驗的(詳見第4章傳輸層)
1.3 TCP/IP中數據的封裝與解封過程
1.4 Internet的管理機構
例如,CNNIC(China Internet Network Information Center),中國互聯網路信息中心
1.5 RFC文檔
RFC(Request for Comments),至今已經發表了數千篇文章,幾乎包含了與計算機通信有關的任何內容,全面地反映了Internet的研究和發展過程.==========================================
第2章 網路介面層
所講都是硬體方面,什麼是網卡,網卡是怎麼做出來的,非硬體人員,跳過
==========================================
第3章 互聯網路層
3.1.1 網路互聯概述
internet(注意小寫)---如果利用網路互聯設備將兩個或多個物理網路相互連接,就形成了互聯網路(internetwork)
Internet(注意大寫)---特指全球范圍內的互聯網
Router---------------將多個物理網路互聯的最常用設備是路由器
Intranet----------如果一個企業內部網路,使用了Internet中的TCP/IP及其網路互聯技術,但不能上網,是一個有限的,封閉的網路
Extranet----------如果一個Intranet通過防火牆等技術與外部Internet相連,則該Intranet就是一個開放的,通過外部可以訪問的網路3.1.2 路由器
(1)路由器的工作原理
if(在同一IP子網) 直接發送到網路上,對方就能收到
else(不在同一IP子網) 發送一個能到達子網的路由,不知道如何傳送的IP報文送給"默認網關",一級級地傳送,IP報文最終送到目的地,達不到目的地的IP報文則被網路丟棄(2)路由器的功能(具有轉發報文和路由選擇兩大功能)3.2 IP數據報格式(分報頭區和數據區兩大部分)
大多是理論知識,要摘抄就全摘抄了.書上介紹的才幾頁,也不太全,具體參考網上,此處不摘抄了,介紹幾種常用網路的MTU值
注意:此節是原始套接字模塊,重點.網上有教材專門講解其模塊.可以參考
---------------------------->以下是總結:第1點:集中在一個點上攻,思路全圍繞它轉,天網恢恢,有一個漏的,當把所有注意點集中在它上時,總會找到這個程序突破處。
以上次寫代碼為例:在程序內找了幾天BUG,一直沒果,最後一個思路我嘆了口氣,將思路放在操作系統上,才幾分鍾就從微軟技術支持網站上找到了,原來此問題是要改注冊表問題(此程序是多線程斷點下載的實例)
第2點:微軟技術支持網站是個很不錯的網站,裡面有很多源代碼,可提供一個方向
第3點:很多代碼在網上是搜索不出來的,必須要相信自己,既然認為這是對的,就一定要堅持下去,各個突破
第4點:當遇上大問題時,離開電腦一段時間(例如下班後或放假),給點獨立空間思考應該怎麼做!
4. Java 請教TCP網路編程裡面的兩個方法的使用!
package chatClient;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;
import org.apache.log4j.Logger;
import DownLoad.*;
import config.*;
public class ChatClient extends JFrame {
private static Logger log=Logger.getLogger(ChatClient.class);
Socket s = null;
TextField tf = new TextField();
TextArea ta = new TextArea(null,11,50,TextArea.SCROLLBARS_VERTICAL_ONLY);
Panel p=new Panel(new GridLayout(2,6,2,3));
Label l3=new Label("下裁的文件名:");
TextField tf1 = new TextField();
Button b3=new Button("下載");
Label l4=new Label("上傳的文件名:");
TextField tf2 = new TextField();
Button b4=new Button("上傳");
Label l1=new Label("用戶名:");
Label l2=new Label("密碼:");
TextField name = new TextField();
JPasswordField pwd=new JPasswordField();
Button b1=new Button("連接");
Button b2=new Button("斷開");
SimpleDateFormat st=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DataOutputStream dos = null;
DataInputStream dis = null;
String cname;
boolean success=false;
boolean start=true;
public static void main(String[] args) {
new ChatClient().launchFrame();
log.debug("test");
log.info("info");
log.error("error");
}
public void launchFrame(){
setLocation(300,333);
p.add(l1);
p.add(name);
p.add(l2);
p.add(pwd);
p.add(b1);
p.add(b2);
p.add(l3);p.add(tf1);p.add(b3);p.add(l4);p.add(tf2);p.add(b4);
ta.setCaretPosition(ta.getText().length());
add(p,BorderLayout.NORTH);
add(tf,BorderLayout.SOUTH);
add(ta,BorderLayout.CENTER);
pack();
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
if(!success){disconnect();}
System.exit(0);
}
});
tf.addActionListener(new TFListener());
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(check()){
connect();
if(!success){
new Thread(new Receve()).start();
}
}else{
JOptionPane.showMessageDialog(null, "用戶名或密碼錯誤,請確認後重輸!");
}
}
});
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
disconnect();
}
});
b3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(tf1.getText().equals("")){
JOptionPane.showMessageDialog(null, "輸入要下裁的文件名!");
}else{
new DownloadStartupC().start(tf1.getText());
}
}
});
b4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(tf2.getText().equals("")){
JOptionPane.showMessageDialog(null, "請輸入要上傳的文件名和路徑!");
}else{
new DownloadStartup().start(tf2.getText());
}
}
});
setVisible(true);
this.setResizable(false);
}
public boolean check(){
cname=name.getText();
String pwd1=pwd.getText();
String pwd2=FileUtil.getMemberData(cname);
if(pwd1.equals(pwd2)){
return true;
}else{
return false;
}
}
public void connect(){
start=true;
try {
s= new Socket (FileUtil.getServerInfoData("serverhost"),Integer.parseInt(FileUtil.getServerInfoData("serverport")));
dos = new DataOutputStream(s.getOutputStream());
dis = new DataInputStream(s.getInputStream());
dos.writeUTF(cname+"登錄 "+st.format(new Date()));
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "伺服器端異常,請稍後重試!");
success=true;
return;
}
success=false;
b1.setEnabled(false);
}
public void disconnect (){
try {
if(dos!=null){
dos.writeUTF(cname+"退出 "+st.format(new Date()));
dos.close();}
if(s!=null){
s.close();}
} catch (IOException e) {
e.printStackTrace();
}
success=true;
b1.setEnabled(true);
}
private class TFListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str = tf.getText();
tf.setText("");
try {
dos.writeUTF(cname+":"+str);
dos.flush();
} catch (Exception e1) {
log.info(e.toString());
JOptionPane.showMessageDialog(null, "未連接,請連接後再發言!");
}
}
}
private class Receve implements Runnable{
public void run() {
try{
while(start){
String s= dis.readUTF();
//if(s.equals("伺服器已關閉,請重新登錄!")){
// start=false;
// b1.setEnabled(true);
// }
ta.setText(ta.getText()+s+'\n');
ta.setCaretPosition(ta.getText().length());
}
} catch(IOException e){
start=false;
b1.setEnabled(true);
// e.printStackTrace();
}
}
}
}
package ChatServer;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import DownLoad.DownloadStartup;
import config.FileUtil;
public class ChatServer extends Frame {
ServerSocket ss = null;
Socket s = null;
boolean start = false;
DataInputStream dis = null;
List clients = new ArrayList();
TextArea ta = new TextArea(null,11,50,TextArea.SCROLLBARS_VERTICAL_ONLY);
JPanel p = new JPanel(new GridLayout(2, 2, 5, 5));
TextField tf = new TextField();
JButton b3 = new JButton("上傳");
JButton b1 = new JButton("start");
JButton b2 = new JButton("stop");
class Client implements Runnable {
private Socket s = null;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean stat = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
stat = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String str) {
try {
dos.writeUTF(str);
} catch (Exception e) {
clients.remove(this);
// e.printStackTrace();
}
}
public void run() {
Client c = null;
try {
while (stat) {
String str = dis.readUTF();
ta.setText(ta.getText()+str+"\n");
ta.setCaretPosition(ta.getText().length());
for (int i = 0; i < clients.size(); i++) {
c = (Client) clients.get(i);
c.send(str);
}
// System.out.println(clients.size());
}
} catch (Exception e) {
//System.out.println("closed!");
} finally {
try {
if (dos != null)
dos.close();
if (dis != null)
dis.close();
if (s != null)
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new ChatServer().launchFrame();
}
public void launchFrame() {
setLocation(300, 333);
this.setSize(300, 300);
this.setTitle("伺服器端");
p.add(b1);
p.add(b2);
p.add(tf);
p.add(b3);
ta.setCaretPosition(ta.getText().length());
add(p, BorderLayout.SOUTH);
add(ta, BorderLayout.CENTER);
pack();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
Thread t=new Thread(new DisConnection());
t.start();
Client c = null;
for (int i = 0; i < clients.size(); i++) {
c = (Client) clients.get(i);
c.send("伺服器已關閉,請稍後重新登錄!");
}
System.exit(0);
}
});
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setTitle("伺服器啟動");
Thread t=new Thread(new Connection());
t.start();
}
});
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setTitle("伺服器關閉");
Thread t=new Thread(new DisConnection());
t.start();
Client c = null;
for (int i = 0; i < clients.size(); i++) {
c = (Client) clients.get(i);
c.send("伺服器已關閉,請稍後重新登錄!");
}
}
});
b3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// System.out.println(tf.getText());
if(tf.getText().equals("")){
JOptionPane.showMessageDialog(null, "請輸入要上傳的文件名和路徑!");
}else{
new DownloadStartup().start(tf.getText());}
}
});
setVisible(true);
}
private class Connection implements Runnable{
public void run() {
try {
ss = new ServerSocket(Integer.parseInt(FileUtil.getServerInfoData("serverport")));
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "伺服器啟動不成功,重試!");
}
try {
start = true;
while (start) {
s = ss.accept();
Client c = new Client(s);
// System.out.println("A Client connected!");
new Thread(c).start();
clients.add(c);
}
} catch (Exception e) {
System.out.println("伺服器關閉");
} finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private class DisConnection implements Runnable{
public void run() {
try {
if(s!=null){
s.close();
}
if(ss!=null){
ss.close();
System.out.println("close");
}
} catch (IOException e) {
e.printStackTrace();
}
try {
FileOutputStream out=new FileOutputStream("Chathistory/history.txt");
out.write(ta.getText().getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
給你個例子 自己看吧
兩個類 可以運行的 你運行起來看看
5. java網路編程中,對於客戶端和伺服器的tcp連接,如果客戶端異常斷開連接,伺服器端如何獲知,有什麼方法
這個得用java心跳處理機制。就是客戶端每隔一段時間向伺服器發送指定信息,如果伺服器沒有收到客服端發來的信息,這時伺服器和客服端連接就已經斷開。具體的心跳實現網路上很多。
6. C語言Linux系統下TCP編程,connect 錯誤
你的client有問題,連接之前沒有指定server的ip。
你只指定了埠。
struct sockaddr_in servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(HELLO_WORLD_SERVER_PORT);
servaddr.sin_addr.s_addr=inet_addr(serverip);//加上server的ip即可
7. TCP網路編程有什麼特點
TCP編程和各基本的編程沒有多大區別,主要的區別在於其中使用函數全是操作系統提供的
Tcp是一種面向連接的,可靠的位元組流服務。(設有數據包編號與差錯控制機制。)
特點:
由於網路的復雜性,傳輸信息時,數據包可能會丟失,差錯控制中的確認機制在接收到數據包是發送確認信息,若是數據包丟失,則回發數據包編號,讓對方重新發送;
由於網路的復雜性,傳輸信息時有多種網路傳送途徑可以選擇,數據包被接收的順序與發送順序不同,可以根據數據包的編號,將數據包重組。
優點:網路連接是以點對點的形式,加上上述特點,保證了數據的安全性,數據包不會中途被劫。
缺點:耗費資源很多
補充:TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基於位元組流的傳輸層通信協議,由IETF的RFC 793定義。在簡化的計算機網路OSI模型中,它完成第四層傳輸層所指定的功能,用戶數據報協議(UDP)是同一層內另一個重要的傳輸協議。在網際網路協議族(Internet protocol suite)中,TCP層是位於IP層之上,應用層之下的中間層。不同主機的應用層之間經常需要可靠的、像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。

8. LINUX網路編程TCP伺服器 客戶端 有亂碼怎麼解決
解決辦法:
1.在客戶端n=read(socketfd,buff,1023);代碼之前加上memset(buff,0,sizeof(buff));,這是保證收到較短數據(使用TCP你不能保證每次接收的數據和發送的數據時等長的),列印也是正確的;
2.將客戶端buff[n+1]+='\0';修改為buff[n]='\0';,這是因為n是下標,已經是最後一個位置了;
3.將伺服器端buff[n+1]+='\0';修改為buff[n]='\0';,這是因為n是下標,已經是最後一個位置了,而且和第2)一樣,那個加號也要去掉,應該是筆誤吧;
4.最大的問題,將伺服器端write(connectfd,buff,1023);,你怎麼能夠保證收到1023個字元呢?也應該將while中條件移出作為WHILE中的一條語句,而且加上前面所述的memset語句,而將這里的write(connectfd,buff,1023);修改為write(connectfd,buff,strlen(buff))。
祝共同進步!
