《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 通信與網(wǎng)絡(luò) > 設(shè)計(jì)應(yīng)用 > 利用socket實(shí)現(xiàn)Windows與Linux平臺(tái)間的網(wǎng)絡(luò)通信
利用socket實(shí)現(xiàn)Windows與Linux平臺(tái)間的網(wǎng)絡(luò)通信
來(lái)源:微型機(jī)與應(yīng)用2013年第18期
周西峰,陸 鵬,郭前崗
(南京郵電大學(xué) 自動(dòng)化學(xué)院,江蘇 南京210023)
摘要: 介紹了socket的工作原理,構(gòu)建出一個(gè)適用于Windows和Linux操作系統(tǒng)的、跨平臺(tái)的網(wǎng)絡(luò)通信程序,并給出設(shè)計(jì)原理和開(kāi)發(fā)步驟。整個(gè)系統(tǒng)采用客戶(hù)機(jī)/服務(wù)器(C/S)模型,在Windows系統(tǒng)中,socket程序利用Visual C#語(yǔ)言編寫(xiě)。Linux系統(tǒng)中的socket程序調(diào)用select()函數(shù),則該套接字自動(dòng)設(shè)置為非阻塞方式,從而提高了程序的執(zhí)行效率。經(jīng)測(cè)試,通信兩端的進(jìn)程能夠通過(guò)各自的套接字收發(fā)消息,從而實(shí)現(xiàn)了Windows與Linux平臺(tái)間的通信。
Abstract:
Key words :

摘  要: 介紹了socket的工作原理,構(gòu)建出一個(gè)適用于Windows和Linux操作系統(tǒng)的、跨平臺(tái)的網(wǎng)絡(luò)通信程序,并給出設(shè)計(jì)原理和開(kāi)發(fā)步驟。整個(gè)系統(tǒng)采用客戶(hù)機(jī)/服務(wù)器(C/S)模型,在Windows系統(tǒng)中,socket程序利用Visual C#語(yǔ)言編寫(xiě)。Linux系統(tǒng)中的socket程序調(diào)用select()函數(shù),則該套接字自動(dòng)設(shè)置為非阻塞方式,從而提高了程序的執(zhí)行效率。經(jīng)測(cè)試,通信兩端的進(jìn)程能夠通過(guò)各自的套接字收發(fā)消息,從而實(shí)現(xiàn)了Windows與Linux平臺(tái)間的通信。
關(guān)鍵詞: 套接字;跨平臺(tái)網(wǎng)絡(luò)通信;客戶(hù)機(jī)/服務(wù)器;select()函數(shù)

    在工業(yè)生產(chǎn)中,人們常把穩(wěn)定性高的Linux系統(tǒng)運(yùn)用到工業(yè)控制領(lǐng)域,以此來(lái)提高控制系統(tǒng)的性能?;赪indows平臺(tái)開(kāi)發(fā)的軟件使用方便,因此工程中的應(yīng)用軟件大多數(shù)是以Windows為平臺(tái)開(kāi)發(fā)的。在一個(gè)工業(yè)系統(tǒng)中,人們需要同時(shí)使用Windows和Linux兩種操作系統(tǒng)。為了使兩個(gè)不同的操作系統(tǒng)能夠協(xié)同工作并互相傳遞消息,需要在兩者間進(jìn)行通信。
    在日常工作中,Windows作為PC機(jī)的操作平臺(tái)被廣泛使用,而Linux也以其開(kāi)放的優(yōu)勢(shì)逐漸被用戶(hù)采用。在兩種系統(tǒng)被普遍使用的前提下,如何實(shí)現(xiàn)資源共享就成了一個(gè)重要的研究課題,需要實(shí)現(xiàn)兩個(gè)平臺(tái)間的互相通信以達(dá)到資源共享的目的。
    基于以上兩點(diǎn),實(shí)現(xiàn)Windows與Linux平臺(tái)間的網(wǎng)絡(luò)通信有著重要的研究意義。本文通過(guò)socket(套接字)編程實(shí)現(xiàn)兩個(gè)系統(tǒng)間的通信,socket是對(duì)應(yīng)TCP/IP協(xié)議的最典型的應(yīng)用開(kāi)發(fā)接口,它提供了不同主機(jī)間進(jìn)程通信的端點(diǎn)。本文闡述了套接字的編程原理,并舉例說(shuō)明如何開(kāi)發(fā)Linux和Windows系統(tǒng)之間的網(wǎng)絡(luò)通信程序。
1 socket基本原理
1.1 基本socket函數(shù)[1]

    socket通信涉及的基本函數(shù)有:
    (1)創(chuàng)建套接字
    sockfd=socket(domain, type, protocol);參數(shù)domain指定socket地址簇類(lèi)型,type為套接字類(lèi)型,protocol指明socket請(qǐng)求的協(xié)議,sockfd為套接字返回的文件描述符。
    (2)綁定套接字與本地地址信息
    bind(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr));該函數(shù)將本地主機(jī)地址以及端口號(hào)與所創(chuàng)建的套接字綁定起來(lái)。
    (3)監(jiān)聽(tīng)連接
    listen(sockfd,backlog);此函數(shù)表示服務(wù)器愿意接收連接,backlog指隊(duì)列中允許的最大排隊(duì)請(qǐng)求的個(gè)數(shù)。
    (4)建立連接
    connect(sockfd,(struct sockaddr*) &server_addr,sizeof(struct sockaddr));connect用于建立連接,server_addr是保存著服務(wù)器IP地址和端口號(hào)的數(shù)據(jù)結(jié)構(gòu)struct sockaddr。
    (5)接收連接請(qǐng)求
    accept(sockfd,(struct sockaddr*) &client_addr,sizeof(struct sockaddr));用于接收客戶(hù)機(jī)發(fā)來(lái)的連接請(qǐng)求。
    (6)發(fā)送數(shù)據(jù)
    send(sockfd,msg,len,flags);將len字節(jié)的數(shù)據(jù)msg發(fā)送出去,flags通常為0。
    (7)接收數(shù)據(jù)
    recv(sockfd,buf,len,flags);從套接字緩沖區(qū)buf中讀取len字節(jié)長(zhǎng)度的數(shù)據(jù)。
    (8)關(guān)閉套接字
    close(sockfd);用于關(guān)閉套接字連接。
1.2 socket通信過(guò)程
    套接字編程采用客戶(hù)機(jī)/服務(wù)器(C/S)[2]模式,連接成功后,雙方可以進(jìn)行通信。通信過(guò)程如圖1所示。

2 軟件設(shè)計(jì)
    為避免使用兩臺(tái)計(jì)算機(jī)的麻煩,在Windows7系統(tǒng)的PC上安裝虛擬機(jī),虛擬機(jī)的操作系統(tǒng)是Linux。這樣就可以在一臺(tái)PC上進(jìn)行通信測(cè)試,主機(jī)為Windows平臺(tái),虛擬機(jī)為L(zhǎng)inux平臺(tái)。
    整個(gè)系統(tǒng)采用客戶(hù)機(jī)/服務(wù)器(C/S)模型,將Linux平臺(tái)作為服務(wù)器端,其IP地址為10.33.17.127,端口號(hào)為3352。將Windows平臺(tái)作為客戶(hù)機(jī)端,其IP地址為10.33.17.126。
2.1 Linux平臺(tái)軟件設(shè)計(jì)
2.1.1 響應(yīng)連接

    分別調(diào)用socket()、bind()、listen()和accept()來(lái)監(jiān)聽(tīng)客戶(hù)機(jī)端的連接請(qǐng)求并與之連接。
2.1.2 select函數(shù)[4]的使用
    select可以完成非阻塞操作,即進(jìn)程執(zhí)行此函數(shù)時(shí)不必等待事件發(fā)生。它能夠監(jiān)視select返回的文件描述符的變化情況,通過(guò)返回值來(lái)判斷select函數(shù)的執(zhí)行情況。
    首先定義一個(gè)集合變量fd_set rfds,分別將標(biāo)準(zhǔn)輸入句柄0和當(dāng)前連接句柄client_fd加入到集合中。先令maxfd為0,再比較client_fd與maxfd的大小,將兩者中較大的值賦給maxfd,即將文件描述符的最大值賦予maxfd。設(shè)置最大等待時(shí)間tv.tv_sec=1,tv.tv_usec=0。
    retval=select(maxfd+1,&rfds,NULL,NULL,&tv),通過(guò)返回值retval判斷文件的讀寫(xiě)情況。若retval為-1,則出錯(cuò);若retval為0,則繼續(xù)等待;若retval為正值,則文件可讀寫(xiě),可以執(zhí)行接下來(lái)的發(fā)送和接收消息的操作。
2.1.3 發(fā)送與接收消息
    if(FD_ISSET(0,&rfds))用來(lái)檢查指定文件描述符0是否在該集合rfds中,若滿(mǎn)足則執(zhí)行發(fā)送操作。fgets(buf,MAXBUF,stdin)表示將鍵盤(pán)輸入的至多MAXBUF個(gè)字符的stdin送到buf中,摁下“Enter”鍵后即可發(fā)送。
    同理,對(duì)于是否接收消息通過(guò)if (FD_ISSET(client_fd,&rfds))來(lái)判斷。
2.1.4 斷開(kāi)連接
    若要斷開(kāi)連接,則輸入“quit”。通過(guò)命令if(!strncasecmp(buf,"quit",4))來(lái)判斷輸入的內(nèi)容是否為quit。連接斷開(kāi)后,顯示框顯示“Client has terminated the communication.”。
2.2 Windows平臺(tái)軟件設(shè)計(jì)
    在Windows系統(tǒng)中,使用C#語(yǔ)言來(lái)編寫(xiě)socket程序。打開(kāi)Microsoft Visual Studio 2010,新建一個(gè)“Windows窗體應(yīng)用程序”的項(xiàng)目。在窗體中添加兩個(gè)button控件,分別為button1(連接)和button2(發(fā)送)。并添加4個(gè)textBox控件,分別為textBox1(消息顯示框)、textBox2(消息輸入框)、textBox3(服務(wù)器IP地址輸入框)和textBox4(服務(wù)器端口號(hào)輸入框)。
2.2.1 請(qǐng)求連接
    新建socket,Server和nPort分別表示服務(wù)器IP地址和端口號(hào),通過(guò)命令socket.Connect(ServerIP,nPort)來(lái)連接服務(wù)器。
2.2.2 發(fā)送與接收消息

 


    定義發(fā)送的字符串為Message,將消息輸入框textBox2中的內(nèi)容指定為Message。通過(guò)發(fā)送命令socket.Send(System.Text.Encoding.Default.GetBytes(Message))進(jìn)行消息發(fā)送。
    新建一個(gè)byte數(shù)組byte[] RecvBuffer,通過(guò)socket.Receive(RecvBuffer)將接收到的內(nèi)容存放到RecvBuffer中。接收成功后,將接收到的內(nèi)容顯示在消息顯示框中。
3 運(yùn)行結(jié)果與分析
3.1 編譯并執(zhí)行Linux端程序

    gcc server_socket.c-o server_scoket
    ./server_socket 3352 Server
    此時(shí),服務(wù)器端程序準(zhǔn)備就緒,等待客戶(hù)端請(qǐng)求連接。
3.2 啟動(dòng)Windows端的連接
    打開(kāi)Microsoft Visual Studio 2010軟件,點(diǎn)擊“啟動(dòng)調(diào)試”鍵后彈出窗體界面。點(diǎn)擊窗體界面中的“連接”鍵后,客戶(hù)機(jī)端能夠成功連接服務(wù)器端。
3.3 實(shí)現(xiàn)互相通信
    連接成功后,服務(wù)器端和客戶(hù)機(jī)端可以自由發(fā)送消息。如圖2所示,Windows系統(tǒng)中,在窗體界面的“消息輸入框”中輸入消息,點(diǎn)擊“發(fā)送”后即可發(fā)送。在Linux終端中,輸入要發(fā)送的消息,點(diǎn)擊“Enter”鍵后進(jìn)行發(fā)送。如圖3所示。

3.4 結(jié)果分析
    結(jié)果表明,服務(wù)器端和客戶(hù)機(jī)端在成功連接后能夠進(jìn)行通信。在Linux系統(tǒng)中,通信結(jié)果在終端顯示。在Windows系統(tǒng)中,通信結(jié)果在窗體界面中顯示。經(jīng)測(cè)試,兩個(gè)平臺(tái)間能夠完成無(wú)數(shù)次的收發(fā)操作。若要結(jié)束通信,在Linux終端中鍵入“quit”,即斷開(kāi)連接。
    本文闡述了Windows與Linux系統(tǒng)的網(wǎng)絡(luò)傳輸設(shè)計(jì)方法,雙方采用TCP/IP協(xié)議,運(yùn)用socket 接口來(lái)開(kāi)發(fā)網(wǎng)絡(luò)通信程序。Windows平臺(tái)利用C#編寫(xiě)socket程序,并通過(guò)窗體界面顯示通信過(guò)程。Linux平臺(tái)中的socket程序調(diào)用select函數(shù),實(shí)現(xiàn)非阻塞操作。套接字使得連接在通信兩端的進(jìn)程,能夠通過(guò)各自的套接字收發(fā)消息,從而實(shí)現(xiàn)了兩個(gè)平臺(tái)間的全雙工通信。目前的通信程序只能傳送字符串,要真正實(shí)現(xiàn)兩個(gè)系統(tǒng)之間的資源共享與消息傳遞,還需要它們之間能夠傳送文件、照片及視頻等大數(shù)據(jù)量的信息,這將是下一階段的研究重點(diǎn)。
參考文獻(xiàn)
[1] 王遠(yuǎn)洋,周淵平,郭煥麗.Linux下基于socket多線(xiàn)程并發(fā)通信的實(shí)現(xiàn)[J].微計(jì)算機(jī)信息,2009,25(5-3):70-72.
[2] 盧寧,李定主,姚暉.Linux和Windows系統(tǒng)之間網(wǎng)絡(luò)通信程序的開(kāi)發(fā)[J].電腦開(kāi)發(fā)與應(yīng)用,2002,15(3):23-24.
[3] 郭勇.利用Socket開(kāi)發(fā)客戶(hù)/服務(wù)器應(yīng)用[J].廣西師范大學(xué)學(xué)報(bào)(自然科學(xué)版),2000,18(1):24-27.
[4] 陳榮軍,謝舜道,譚洪舟,等.一種基于Select函數(shù)的嵌入式網(wǎng)絡(luò)通信信息轉(zhuǎn)發(fā)機(jī)制設(shè)計(jì)[J].電腦知識(shí)與技術(shù),2013,9(1):25-28.

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。