久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3311|回復: 0
收起左側

單片機串口通信原理實現的上下位機設計

[復制鏈接]
ID:698492 發表于 2020-2-26 13:38 | 顯示全部樓層 |閱讀模式
本文轉自:Flywithliye

1.  通信簡介
通信有并行通信和串行通信兩種方式。在多微機系統以及現代測控系統中信息的交換多采用串行通信方式。
1)  并行通信
并行通信是指所傳送的數據各位同時進行傳送。其優點是傳送速度快,缺點是傳輸線多,通信線路費用較高,并行傳送適用于近距離、傳送速度高的場合。
2)  串行通信
串行通信時,傳送數據的各位按分時順序一位一位地傳送(例如先低位、后高位)。其優點是傳輸線少,傳送通道費用低,故適合長距離數據傳送。缺點是傳送速度較低。
圖 1
2.  串行通信1)  串行通訊數據傳送方向a)  單工方式
通信雙方只有一條單向傳輸線,只允許數據由一方發送,另一方接收。
b)  半雙工方式
通信雙方只有一條雙向傳輸線,允許數據雙向傳送,但每時刻上只能有一方發送,另一方接收,這是一種能夠切換傳送方向的單工方式。
c)  全雙工方式
通信雙方只有兩條傳輸線,允許數據同時雙向傳送,其通信設備應具有完全獨立的收發功能。
圖 2
2)  串行通信基本方式
為了準確地發送、接收信息,發送者和接受者雙方必須協調工作。這種協調方法,從原理上可分成兩種:同步串行I/O和異步串行I/O。
a)  同步通信方式
在同步通信中,在數據或字符開始傳送前用同步字符(SYNC)來指示(常約定l一2個),由時鐘來實現發送端和接收端同步,當檢測到規定的同步字符后,接下來就連續按順序傳送數據。同步字符是一特定的二進制序列,在傳送的數據中不會出現。
同步通信方式由于不采用起始和停止位,是在同步字符后可以接較大的數據區,同步字符所占部分很小,因此有較高的傳送效率。
發送、接收雙方都由統一的時鐘來發送、接收數據。也就是說,不光有數據傳輸線,還要附加同步時鐘線。這種方式,硬件較復雜、成本較高、傳送速率高。
b)  異步通信方式
異步通信方式時,數據一幀一幀地傳送,不需要同步時鐘,實現簡單。
在異步方式中,為了避免連續傳送過程中的誤差積累,每個字符都要獨立確定起始和結束(即每個字符都要重新同步),字符和字符間還可能有長度不定的空閑時間。
3)  異步串行通信數據格式
一個字符在異步傳送中稱為一幀數據。一幀數據由4部分組成:起始位、數據位、奇偶位、停止位。
圖 3
上圖所示為不包含奇偶檢驗位的一個數據幀。奇偶檢驗位應位于數據位后,停止位前。
a)  起始位
在沒有數據傳輸時,通信線上處于邏輯“1”狀態。當發送端要發送1個字符數據時,首先發送1個邏輯“0”,這個低電平便是幀格式的起始位。其作用是向接收端表示發送端開始發送一幀數據了。接收端檢測到這個低電平后,就準備接收數據。
b)  數據位
在起始位之后,發送端發出(或接收端接收)的是數據位,數據的位數沒有嚴格的限制,5~8 位均可。由低位到高位逐位發送。
c)  奇偶校驗位
數據位發送完(接收完)之后,可發送一位用來驗證數據在傳送過程中是否出錯的奇偶校驗位。奇偶校驗是收發雙發預先約定的有限差錯校驗方法之一。有時也可不用奇偶校驗。
d)  停止位
字符幀格式的最后部分是停止位,邏輯“高(1)”電平有效,它可占 1/2 位、1 位或 2 位。停止位表示傳送一幀信息的結束,也為發送下一幀數據做好了準備。
4)  串行接口標準a)  RS-232
RS-232是美國電子工業協會EIA(Electronic Industry Association)制定的一種串行物理接口標準。RS是英文“推薦標準”的縮寫,232為標識號。RS-232是對電氣特性以及物理特性的規定,只作用于數據的傳輸通路上,它并不內含對數據的處理方式。RS-232標準是邏輯1為-3V~-15V,邏輯0為+3~+15V。
b)  RS-422
RS-422的電氣性能與RS-485完全一樣。主要的區別在于:RS-422 有4 根信號線:兩根發送、兩根接收。由于RS-422 的收與發是分開的所以可以同時收和發(全雙工),也正因為全雙工要求收發要有單獨的信道,所以RS-422適用于兩個站之間通信,星型網、環網,不可用于總線網;RS-485 只有2 根信號線,所以只能工作在半雙工模式,常用于總線網。
c)  RS-485
RS-232接口可以實現點對點的通信方式,但這種方式不能實現聯網功能。于是,為了解決這個問題,一個新的標準RS-485產生了。RS-485的數據信號采用差分傳輸方式,也稱作平衡傳輸,它使用一對雙絞線,將其中一線定義為A,另一線定義為B。通常情況下,發送驅動器A、B之間的正電平在+2~+6V,是一個邏輯狀態,負電平在-2~-6V,是另一個邏輯狀態。另有一個信號地C,在RS-485中還有一“使能”端,而在RS-422中這是可用可不用的。
3.  通信實驗1)  實驗環境的搭建
為實現在無附加硬件的條件下,使用PC機完成串行口通信實驗。通過軟件對實驗環境配置如下:
a)  虛擬串口的創建
使用Configure Virtual Serial Port Driver軟件在PC上創建一對虛擬串口(COM1和COM2),如圖所示。
圖 4
COM1和COM2為已連接的一對串口,分別為兩臺設備的接口(已虛擬連接)。設備A,B分別連接至COM1和COM2,即可收發數據。
b)  設備B的創建
此次實驗中,設備B為單片微機(MCU)。其選型為AT89C52型,具備硬件UART功能。設備B電路實現由Protues軟件進行模擬仿真。電路原理圖如圖所示。
圖 5
由于RS-232標準采用負邏輯,即邏輯1為-3V~-15V,邏輯0為+3~+15V。而本單片機系統為TTL信號系統。TTL電平規定,+5V等價于邏輯“1”,0V等價于邏輯“0”。因此,DB-9與單片機的連接需要進行電平轉換,如上圖所示,選用了MAX232芯片。
圖 6
如圖所示,P1組件(COMPIM)即為DB-9接口,使用MAX232芯片進行電平轉換后與AT89C52串行口P3.0/RXD,P3.1/TXD分別相連接。(由于軟件特殊原因,在MAX232芯片1通道R1OUT及T1OUT處增加74LS04非門進行處理,實際中無需取反處理。)
圖中組件RECEIVE和SEND為Protues軟件提供的VIRTUAL TERMINAL(虛擬終端)可用于觀察AT89C52接收和發送到的數據。僅用于調試觀察。
2)  實驗內容說明
本次實驗涉及兩個設備,設備B為上述單片微機,用以模擬一個外部設備。設備A為PC機本身。
設備A,B分別都運行有簡單的程序。設備A的程序存儲器中加載有簡單回傳程序,負責將接收到的字符/字符串(以回車換行結尾)保持原接收狀態并向外發送。設備B即PC,其上運行有窗口程序,負責向設備A發送字符/字符串,并接收顯示其回傳的數據。
實驗時設備A連接COM1口,設備B連接COM2口。由PC窗口程序輸入測試數據后發送至單片微機后,由后者保持原樣回傳并顯示在PC窗口程序接收窗口。
3)  單片機程序的編制
由于該芯片自帶硬件UART功能且由于實驗環境所限,此次實驗中,發送接收通過配置相關寄存器控制硬件模塊實現,未采用軟件定時器模擬通信時序的方式。
程序主要包括以下三個部分:主函數,串行口配置函數,發送函數及串行口中斷服務函數。
a)  程序變量定義及函數聲明
b)  程序主函數
c)  其他子函數
其他在主函數中調用的具體子函數實現由附件1列出。
4)  窗口應用程序的編制
本次實驗的窗口程序使用VB.NET語言在VS2010環境下編寫。
程序中主要由.NET提供的SerialPort控件實現,輔之以必要的其他窗口控件。窗口布局如圖所示:
圖 7
a)  參數設置函數
b)  數據接收函數
SerialPort的事件DataReceived調用Sp_Receiving實現數據接收。當輸入緩沖區接收到1個字符后驅動該事件發生,并調用Sp_Receiving函數準備開始接收數據。當讀取到緩沖區中的回車換行符后,將接受到的數據顯示在TextBox控件中。若在超時以后仍未讀取到回車換行符,則執行空操作后退出接受程序,退出前清空接收緩沖區。既本窗口程序僅接受并顯示以回車換行結尾的數據包。
c)  數據發送函數
數據發送過程由按鍵按下事件驅動調用。判斷是否發送新行(本次實驗中必須勾選)后是否為對話模式后,發送數據。
d)  其他子函數
其他子函數包括PC可用串口讀取,串口打開,串口關閉,及相關事件處理函數。其具體實現由附件2給出。
5)  實驗過程a)  串口有關參數設置
表 1
串口參數約定

設備A(PC)
設備B(MCU)
COM編號
COM1
COM2
波特率(bps)
9600
數據位
8
校驗位
停止位
1
按照表1設置串口參數如下。
圖 8
圖 9

左圖為窗口程序設置,右圖為仿真軟件中對與MCU接口的DB-9接頭的屬性設置。MCU中的配置由配置相關寄存器完成,如下所示。
b)  啟動MCU仿真
點擊下圖第一個按鈕啟動仿真。
圖 10
出現如下圖所示內容說明仿真成功執行。
圖 11
c)  打開上位機串口
點擊打開串口按鍵,若在串口狀態處顯示已打開,則說明上位機以成功打開串口。
圖 12
d)  輸入信息并發送
在發送輸入下的文本框中輸入任意字符串(長度不可超出單片機接收緩沖區長度-2)后,點擊右側發送按鈕。此處發送“This is a test!”。
圖 13
e)  單片機回傳數據
上位機發送數據“This is a test!”之后,單片機回傳“MCU received: This is a test!”并顯示在接收顯示窗口中,如下圖所示。
圖 14
f)  單片機接收/發送
在步驟e)執行之前,單片機接收到的內容和發送的內容如下圖所示。
圖 15
圖 16


2、  TCP通信1.  Socket套接字1)  簡介
網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。
套接字(socket)是通信的基石,是支持TCP/IP協議的網絡通信的基本操作單元。它是網絡通信過程中端點的抽象表示,包含進行網絡通信必須的五種信息:連接使用的協議,本地主機的IP地址,本地進程的協議端口,遠地主機的IP地址,遠地進程的協議端口。
Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把復雜的TCP/IP協議族隱藏在Socket接口后面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數據,以符合指定的協議。
2)  分類
TCP/IP的socket提供下列三種類型套接字。
a)  流式套接字(SOCK_STREAM)
提供了一個面向連接(TCP)、可靠的數據傳輸服務,數據無差錯、無重復地發送,且按發送順序接收。內設流量控制,避免數據流超限;數據被看作是字節流,無長度限制。文件傳送協議(FTP)即使用流式套接字。
b)  數據報式套接字(SOCK_DGRAM)
提供了一個無連接服務(UDP)。數據包以獨立包形式被發送,不提供無錯保證,數據可能丟失或重復,并且接收順序混亂。網絡文件系統(NFS)使用數據報式套接字。
c)  原始式套接字(SOCK_RAW)
該接口允許對較低層協議,如IP、ICMP直接訪問。常用于檢驗新的協議實現或訪問現有服務中配置的新設備。
2.  TCP簡介
TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。利用TCP協議進行通信時,首先要建立通信雙方的連接。一旦連接建立完成,就可以進行通信。TCP提供了數據確認和數據重傳機制,保證了發送的數據一定能到達通信的對方。
3.  TCP通信過程
TCP通信過程如下圖所示。
圖 17
服務器端先初始化Socket,然后與端口綁定(bind),對端口進行監聽(listen),調用(accept)阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然后連接服務器(connect),如果連接成功,這時客戶端與服務器端的連接就成功建立。客戶端發送數據請求,服務器端接收請求并處理請求,然后把回應數據發送給客戶端,客戶端讀取數據,最后關閉連接,一次交互結束。
4.  TCP服務器程序流程1)  建立連接階段
  • 調用socket(),分配文件描述符,即監聽套接字。
  • 調用bind(),將套接字與本地IP地址和端口綁定。
  • 調用listen(),監聽特定端口,socket()創建的套接字是主動的,調用listen使得該文件描述符為監聽套接字,變主動為被動。
  • 調用accept(),阻塞等待客戶端連接。
2)  數據交互階段
  • 調用read(),阻塞等待客戶端發送請求,收到請求后從read()返回,處理客戶端請求。
  • 調用write(),將處理結果發送給客戶端,然后繼續調用read()等待客戶端請求。
3)  關閉連接
  • read()返回0的時候,說明客戶端發來了FIN數據包,即關閉連接,也會調用close()關閉連接套接字和監聽套接字。
5.  TCP客戶端程序流程1)  建立連接階段
  • 調用socket(),分配文件描述符。
  • 調用connect(),向服務器發送建立連接請求。
2)  數據交互階段
  • 調用write(),將請求發送給服務器。
  • 調用read(),阻塞等待服務器應答。
3)  關閉連接
  • 當沒有數據發送的時候,調用close()關閉連接套接字,即關閉連接,向服務器發送FIN數據報。
6.  通信實驗1)  實驗環境的搭建
在編寫實驗程序前,須在編譯器中添加庫文件ws2_32.lib。可通過編譯器軟件設置實現,也可通過包含如下代碼實現:#pragma comment(lib,"ws2_32.lib")
2)  實驗內容說明
本次實驗包括服務器端程序和客戶端程序,由C語言編寫的控制臺程序實現。程序順序執行。實驗實現客戶端程序和服務器端程序的通信(字符串)。
3)  服務器端程序的編制a)  程序變量定義及函數聲明
b)  程序主函數
c)  其他子函數
其他子函數包括用于初始化套接字,創建套接字,綁定IP和端口,設置監聽狀態,等待客戶端發起連接的程序,其中分別調用了Socket中提供的功能函數,但是加入了一些簡單的顯示和錯誤處理。其具體實現由附件3給出。
4)  客戶端程序的編制a)  程序變量定義及函數聲明
b)  程序主函數
c)  其他子函數
其他子函數包含用于初始化套接字,創建套接字,連接服務器及釋放套接字的函數。為了適應在本地實驗和同網段實驗的需求,連接服務器的子函數Connect_Socket()中從鍵盤獲取輸入的IP地址和端口實現連接。其具體實現由附件4給出。
5)  實驗過程a)  啟動服務器端程序并等待連接b)  啟動客戶端程序并發起連接
輸入服務器IP地址和端口后即可發起連接。
c)  客戶端發送消息
輸入消息并回車即可發送。
圖 18
圖 19
d)  服務器端發送消息
輸入消息并回車即可發送。
注意:由于程序順序/循環執行,非事件驅動結構,因此必須在接收到對方發送的數據后,己方方可發送。
3、  UDP通信1.  UDP簡介
UDP是無連接的不可靠的傳輸協議。采用UDP進行通信時,不需要建立連接,可以直接向一個IP地址發送數據,但是不能保證對方能收到。
對于基于UDP面向無連接的套接字編程來說,服務器端和客戶端這種概念不是特別的嚴格。可以把服務器端稱為接收端,客戶端就是發送數據的發送端。
2.  UDP通信過程
圖 20
服務器端先初始化Socket,然后與端口綁定(bind),在這時如果有個客戶端初始化一個Socket,客戶端發送數據請求,服務器端接收請求并處理請求,然后把回應數據發送給客戶端,客戶端讀取數據,一次交互結束。
注意到,在進行端口綁定(bind)之后,服務器端不需要對端口進行監聽(listen),也不需要調用等待連接(accept)阻塞,等待客戶端連接。而客戶端無需使用連接(connect)事先與服務器建立連接。
3.  UDP服務器程序流程
  • 建立套接字文件描述符,使用函數socket(),生成套接字文件描述符。
  • 設置服務器地址和偵聽端口,初始化要綁定的網絡地址結構。
  • 綁定偵聽端口,使用bind()函數,將套接字文件描述符和一個地址類型變量進行綁定。
  • 接收客戶端的數據,使用recvfrom()函數接收客戶端的網絡數據。
  • 向客戶端發送數據,使用sendto()函數向服務器主機發送數據。
  • 關閉套接字,使用close()函數釋放資源。UDP協議的客戶端流程.
4.  UDP客戶端程序流程
  • 建立套接字文件描述符,socket()
  • 設置服務器地址和端口,struct sockaddr
  • 向服務器發送數據,sendto()
  • 接收服務器的數據,recvfrom()
  • 關閉套接字,close()
5.  通信實驗1)  實驗內容說明
本次實驗進行了更為簡單的驗證次實驗啟動服務器后監聽某端口后,由客戶端發送一固定數據給服務器,服務器接收并顯示后。雙方釋放套接字并結束程序。
2)  服務器端程序的編制a)  程序變量定義及函數聲明
b)  程序主函數
c)  其他子函數
其他子函數包括用于初始化套接字,綁定IP和端口的函數,其中分別調用了Socket中提供的功能函數。其具體實現由附件5給出。
3)  客戶端程序的編制a)  程序變量定義及函數聲明
b)  程序主函數
c)  其他子函數
其他子函數包括用于初始化套接字,設置服務器IP和端口的函數,其中分別調用了Socket中提供的功能函數。其具體實現由附件6給出。
4)  實驗過程a)  啟動服務器并監聽端口b)  啟動客戶端向服務器發送c)  服務器接收并顯示
圖 21
圖 22

5.  附件五(UDP Server程序)
  #include<stdio.h>  
  #include<winsock.h>                           /*引入winsock頭文件*/  
  #pragma comment(lib,"ws2_32.lib")  
   
  char Receivebuf[100];       /*接受數據的緩沖區*/  
  int length;  
   
  SOCKET socket_send;         /*定義套接字*/  
  SOCKADDR_IN Server_add;     /*服務器地址信息結構*/  
SOCKADDR_IN Client_add;     /*客戶端地址信息結構*/  
WORD wVersionRequested;     /*字(word):unsigned short*/  
WSADATA wsaData;            /*庫版本信息結構*/  
int error;                  /*表示錯誤*/  
  
void Init_Socket();         /*初始化套接字*/  
void Bind_Socket();         /*綁定套接字*/  
  
int main()  
{  
    memset(Receivebuf,0,100);                  /*清空接收緩沖*/  
    Init_Socket();                             /*初始化套接字*/  
  
    socket_send=socket(AF_INET,SOCK_DGRAM,0);  /*創建套接字*/  
    Bind_Socket();                             /*綁定套接字*/  
      
    recvfrom(socket_send,Receivebuf,100,0,(SOCKADDR*)&Client_add,&length);  
    printf("客戶端:%s\n",Receivebuf);         /*接收并顯示數據*/  
  
    closesocket(socket_send);                  /*釋放套接字資源*/  
    WSACleanup();                              /*關閉動態鏈接庫*/  
    system("pause");  
    return 0;  
}  
  
void Init_Socket()  
{  
    /*-------------------------初始化套接字庫---------------------------*/  
    /*定義版本類型。將兩個字節組合成一個字,前面是第字節,后面是高字節*/  
    wVersionRequested = MAKEWORD( 2, 2 );     
    /*加載套接字庫,初始化Ws2_32.dll動態鏈接庫*/  
    error = WSAStartup( wVersionRequested, &wsaData);     
    if(error!=0)  
    {  
        printf("加載套接字失敗!\n");  
        return 0;                              /*程序結束*/  
    }  
    /*判斷請求加載的版本號是否符合要求*/  
    if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2)   
    {     
        WSACleanup( );                         /*不符合,關閉套接字庫*/  
        return 0;                              /*程序結束*/  
    }  
    printf("加載套接字成功。\n");  
}  
  
void Bind_Socket()  
{  
    /*----------------------設置服務器地址-----------------------*/  
    Server_add.sin_family=AF_INET;/*地址家族,對于必須是AF_INET,注意只有它不是網絡網絡字節順序*/  
    Server_add.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  
    Server_add.sin_port=htons(5000);/*端口號*/  
  
    /*綁定套接字*/  
    bind(socket_send,(SOCKADDR*)&Server_add,sizeof(SOCKADDR));  
    length=sizeof(SOCKADDR);  
    printf("綁定成功。\n正在監聽\n");  
}  

6.  附件六(UDP Client程序)
  #include<stdio.h>  
  #include<winsock.h>               /*引入winsock頭文件*/  
  #pragma comment(lib,"ws2_32.lib")  
   
  #define Msg "This is a test!"   /*待發送數據*/  
  SOCKET socket_client;           /*定義套接字*/  
  SOCKADDR_IN Server_add;         /*服務器地址信息結構*/  
  WORD wVersionRequested;         /*字(word):unsigned short*/  
  WSADATA wsaData;                /*庫版本信息結構*/  
int error;                      /*表示錯誤*/  
  
void Init_Socket();             /*初始化套接字*/  
void Set_Server();              /*設置服務器地址和端口*/  
int main()  
{  
    Init_Socket();                                 /*初始化套接字*/                                       
    socket_client=socket(AF_INET,SOCK_DGRAM,0);    /*創建套接字*/  
    Set_Server();                                  /*設置服務器地址和端口*/  
    /*發送數據*/  
    sendto(socket_client,Msg,strlen(Msg)+1,0,(SOCKADDR*)&Server_add,sizeof(SOCKADDR));  
    printf("已發送數據至服務器\n");  
    closesocket(socket_client);                    /*釋放套接字資源*/  
    WSACleanup();                                  /*關閉動態鏈接庫*/  
    system("pause");  
    return 0;  
}  
  
void Init_Socket()  
{  
    /*-------------------------初始化套接字庫---------------------------*/  
    /*定義版本類型。將兩個字節組合成一個字,前面是第字節,后面是高字節*/  
    wVersionRequested = MAKEWORD( 2, 2 );     
    /*加載套接字庫,初始化Ws2_32.dll動態鏈接庫*/  
    error = WSAStartup( wVersionRequested, &wsaData);     
    if(error!=0)  
    {  
        printf("加載套接字失敗!\n");  
        return 0;                                  /*程序結束*/  
    }  
    /*判斷請求加載的版本號是否符合要求*/  
    if ( LOBYTE( wsaData.wVersion ) != 2 ||  
           HIBYTE( wsaData.wVersion ) != 2 )   
    {     
        WSACleanup( );                             /*不符合,關閉套接字庫*/  
        return 0;                                  /*程序結束*/  
    }  
    printf("加載套接字成功。\n");  
}  
  
void Set_Server()  
{  
    /*----------------------設置服務器地址-----------------------*/  
    Server_add.sin_family=AF_INET;/*地址家族,對于必須是AF_INET,注意只有它不是網絡網絡字節順序*/  
    Server_add.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  
    Server_add.sin_port=htons(5000);               /*端口號*/  
    printf("服務器設置成功。\n");  
}  


4.  附件四(TCP Client程序)
  #include<stdio.h>  
  #include<winsock.h>       /*引入winsock頭文件*/  
  #pragma comment(lib,"ws2_32.lib")  
   
  char Sendbuf[100];      /*發送數據的緩沖區*/  
  char Receivebuf[100];   /*接受數據的緩沖區*/  
  int SendLen;            /*發送數據的長度*/  
  int ReceiveLen;         /*接收數據的長度*/  
  char IPaddress[16];     /*IP地址數組*/  
char Port[6];           /*端口數組*/  
  
SOCKET socket_send;     /*定義套接字*/  
SOCKADDR_IN Server_add; /*服務器地址信息結構*/  
WORD wVersionRequested; /*字(word):unsigned short*/  
WSADATA wsaData;        /*庫版本信息結構*/  
int error;              /*表示錯誤*/  
  
int Init_Socket();      /*初始化套接字*/  
void Create_Socket();   /*創建套接字*/  
void Connect_Socket();  /*連接服務器*/  
void Close_Socket();    /*釋放套接字*/  
  
int main()  
{  
    Init_Socket();                                      /*初始化套接字*/  
    Create_Socket();                                    /*創建套接字*/  
    Connect_Socket();                                   /*連接服務器*/  
  
    while(1)                                            /*具體通信過程*/  
    {     
        /*---------------發送數據過程----------*/  
        printf("請輸入消息:");  
        gets(Sendbuf);                                  //獲取輸入的數據  
        SendLen = send(socket_send,Sendbuf,100,0);      //啟動發送  
        if(SendLen < 0)  
        {  
            printf("發送失敗!\n");                      //發送失敗  
            break;  
        }  
  
        /*--------------接收數據過程---------------*/  
        ReceiveLen =recv(socket_send,Receivebuf,100,0); //結束數據存緩沖區  
        if(ReceiveLen<0)  
        {  
            printf("連接關閉或接收失敗\n程序退出\n");   //接收或連接失敗  
            break;  
        }  
        else                                             
        {  
            printf("來自服務器:%s\n",Receivebuf);      //顯示收到的數據  
        }     
    }  
    Close_Socket();                                     /*釋放套接字*/  
    return 0;  
}  
  
int Init_Socket()  
{  
    /*------------初始化套接字庫---------------*/  
    /*定義版本類型。將兩個字節組合成一個字,前面是第字節,后面是高字節*/  
    wVersionRequested = MAKEWORD( 2, 2 );     
    /*加載套接字庫,初始化Ws2_32.dll動態鏈接庫*/  
    error = WSAStartup( wVersionRequested, &wsaData);     
    if(error!=0)  
    {  
        printf("加載套接字失敗。\n");  
        return 0;                                       /*程序結束*/  
    }  
    else  
    {  
        printf("加載套接字成功。\n");  
    }  
    /*判斷請求加載的版本號是否符合要求*/  
    if(LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2)   
    {     
        WSACleanup( );                                  /*不符合,關閉套接字庫*/  
        return 0;                                       /*程序結束*/  
    }  
    else  
    {  
        printf("加載版本號符合。\n");  
    }  
}  
  
void Create_Socket()  
{  
    /*-------------進行連接服務器--------------*/  
    /*客戶端創建套接字,但是不需要綁定的,只需要和服務器建立起連接就可以了。*/  
    /*socket_sendr表示的是套接字,Server_add服務器的地址結構*/  
    socket_send=socket(AF_INET,SOCK_STREAM,0);  
}  
  
void Connect_Socket()  
{  
    /*------------設置服務器地址---------------*/  
    Server_add.sin_family=AF_INET;/*地址家族,對于必須是AF_INET,注意只有它不是網絡網絡字節順序*/  
    /*服務器的地址,將一個點分十進制表示為IP地址,inet_ntoa是將地址轉成字符串*/  
    puts("輸入IP地址:");  
    gets(IPaddress);  
    puts("輸入端口:");  
    gets(Port);  
    Server_add.sin_addr.S_un.S_addr = inet_addr(IPaddress);  
    Server_add.sin_port=htons(atoi(Port));              /*端口號*/  
    /*-------------創建用于連接的套接字--------*/  
    /*AF_INET表示指定地址族,SOCK_STREAM表示流式套接字TCP,特定的地址家族相關的協議。*/  
    if(connect(socket_send,(SOCKADDR*)&Server_add,sizeof(SOCKADDR)) == SOCKET_ERROR)  
    {  
        printf("服務器連接失敗。\n");  
    }  
    else  
    {  
        printf("服務器連接成功。\n");  
    }  
}  
  
void Close_Socket()  
{  
    /*---------釋放套接字,關閉動態庫----------*/  
    closesocket(socket_send);   /*釋放套接字資源*/  
    WSACleanup();               /*關閉動態鏈接庫*/  
}  

3.  附件三(TCP Server程序)
      #include<stdio.h>  
  #include<winsock.h>       /*引入winsock頭文件*/  
  #pragma comment(lib,"ws2_32.lib")  
   
  #define IPaddress "127.0.0.1" /*IP地址*/  
  #define Port "5000"           /*端口*/  
   
  char Sendbuf[100];      /*發送數據的緩沖區*/  
  char Receivebuf[100];   /*接受數據的緩沖區*/  
int SendLen;            /*發送數據的長度*/  
int ReceiveLen;         /*接收數據的長度*/  
int Length;             /*表示SOCKADDR的大小*/  
  
SOCKET socket_server;   /*定義服務器套接字*/  
SOCKET socket_receive;  /*定義用于連接套接字*/  
SOCKADDR_IN Server_add; /*服務器地址信息結構*/  
SOCKADDR_IN Client_add; /*客戶端地址信息結構*/  
WORD wVersionRequested; /*字(word):unsigned short*/  
WSADATA wsaData;        /*庫版本信息結構*/  
int error;              /*表示錯誤*/  
  
int Init_Socket();      /*初始化套接字*/  
void Create_Socket();   /*創建套接字*/  
int Bind_Socket();      /*綁定IP和端口*/  
int Listen_Socket();    /*設置監聽狀態*/  
int Wait_Socket();      /*等待客戶端連接*/  
void Close_Socket();    /*釋放套接字*/  
  
int main()  
{  
    Init_Socket();                                            /*初始化套接字*/  
    Create_Socket();                                          /*創建套接字*/  
    Bind_Socket();                                            /*綁定IP和端口*/  
    Listen_Socket();                                          /*設置監聽狀態*/  
    Wait_Socket();                                            /*等待客戶端連接*/  
      
    while(1)            /*具體通信過程*/  
    {     
        /*--------接收數據---------*/  
        ReceiveLen =recv(socket_receive,Receivebuf,100,0);    //接收數據存緩沖區  
        if(ReceiveLen<0)                                      //連接或接收失敗  
        {  
            printf("客戶端中斷連接或接收失敗\n程序退出\n");  
            break;  
        }  
        else  
        {  
            printf("來自客戶端:%s\n",Receivebuf);            //顯示接收到的數據  
        }     
         
        /*--------發送數據---------*/  
        printf("請輸入消息:");  
        gets(Sendbuf);                                        //獲取輸入的數據  
        SendLen=send(socket_receive,Sendbuf,100,0);           //啟動發送  
        if(SendLen<0)  
        {  
            printf("發送失敗。\n");                           //本次發送失敗  
            break;  
        }  
    }  
    Close_Socket();                                           /*釋放連接*/  
    return 0;  
}  
  
int Init_Socket()  
{  
    /*------------初始化套接字庫---------------*/  
    /*定義版本類型。將兩個字節組合成一個字,前面是第字節,后面是高字節*/  
    wVersionRequested = MAKEWORD( 2, 2 );     
    /*加載套接字庫,初始化Ws2_32.dll動態鏈接庫*/  
    error = WSAStartup( wVersionRequested, &wsaData);     
    if(error!=0)  
    {  
        printf("加載套接字失敗。\n");  
        return 0;                                             /*程序結束*/  
    }  
    else  
    {  
        printf("加載套接字成功。\n");  
    }  
    /*判斷請求加載的版本號是否符合要求*/  
    if(LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2)   
    {     
        WSACleanup( );                                        /*不符合,關閉套接字庫*/  
        return 0;                                             /*程序結束*/  
    }  
    else  
    {  
        printf("加載版本號符合。\n");  
    }  
    return 1;  
}  
  
void Create_Socket()  
{  
    /*------------設置連接地址-----------------*/  
    Server_add.sin_family=AF_INET;/*地址家族,對于必須是AF_INET,注意只有它不是網絡網絡字節順序*/  
    Server_add.sin_addr.S_un.S_addr=inet_addr(IPaddress);     /*主機地址*/  
    Server_add.sin_port=htons(atoi(Port));/*端口號*/  
  
    /*------------創建套接字-------------------*/  
    /*AF_INET表示指定地址族,SOCK_STREAM表示流式套接字TCP,特定的地址家族相關的協議。*/  
    socket_server=socket(AF_INET,SOCK_STREAM,0);  
}  
  
int Bind_Socket()  
{  
    /*---綁定套接字到本地的某個地址和端口上----*/  
    /*socket_server為套接字,(SOCKADDR*)&Server_add為服務器地址*/  
    if(bind(socket_server,(SOCKADDR*)&Server_add,sizeof(SOCKADDR) )==SOCKET_ERROR)  
    {  
        printf("綁定失敗。\n");  
        return 0;  
    }  
    else  
    {  
        printf("套接字綁定成功。\n");  
        printf("當前主機地址:");  
        printf(IPaddress);  
        printf("\n當前主機端口:");  
        printf(Port);  
        printf("\n");  
    }  
    return 1;  
}  
  
int Listen_Socket()  
{  
    /*------------設置套接字為監聽狀態---------*/  
    /*監聽狀態,為連接做準備,最大等待的數目為5*/  
    if(listen(socket_server,5)<0)  
    {  
        printf("監聽失敗\n");  
        return 0;  
    }  
    else  
    {  
        printf("監聽成功\n");  
        return 1;  
    }  
}  
  
int Wait_Socket()  
{  
    /*------------接受連接---------------------*/  
    Length=sizeof(SOCKADDR);  
    /*接受客戶端的發送請求,等待客戶端發送connect請求*/  
    socket_receive=accept(socket_server,(SOCKADDR*)&Client_add,&Length);  
    if(socket_receive==SOCKET_ERROR)  
    {  
        printf("客戶端連接失敗。");  
        return 0;  
    }  
    else  
    {  
        printf("客戶端連接成功。\n");  
        return 1;  
    }  
}  
  
void Close_Socket()  
{  
    /*---------釋放套接字,關閉動態庫----------*/  
    closesocket(socket_receive);                              /*釋放客戶端的套接字資源*/  
    closesocket(socket_server);                               /*釋放套接字資源*/  
    WSACleanup();                                             /*關閉動態鏈接庫*/  
}  

7.  附件七(單片機原理圖)




轉自 Flywithliye 相關資料下載:http://www.zg4o1577.cn/bbs/dpj-180566-1.html

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品久| 色资源在线观看 | 国产精品九九九 | 久久大| 国产黄色在线观看 | 久久人爽 | 久久久精彩视频 | 毛片一区二区三区 | 天堂视频一区 | 密乳av| 日本视频在线播放 | 欧美一级电影免费观看 | 日韩插插 | 欧美一区二区三区大片 | 黄网站免费在线观看 | a天堂在线| 国产综合网站 | 久久亚洲精品国产精品紫薇 | 国产伦精品一区二区 | 91精品国产综合久久久久久丝袜 | 亚洲三级国产 | 狠狠av| 色约约视频 | 爱高潮www亚洲精品 中文字幕免费视频 | 精品久久久久久亚洲综合网 | 日本精品视频在线观看 | 伊人免费视频二 | 96久久久久久 | 操操操av| 黄a网| 九九久久国产精品 | aaa国产大片| 亚洲欧洲av在线 | 浮生影院免费观看中文版 | 国产精品欧美一区二区三区不卡 | 中文字幕精| 伦理午夜电影免费观看 | 国产黄色麻豆视频 | 国产一区二区三区在线 | 一区二区三区欧美在线观看 | 欧美激情久久久 |