⑴ 如何學習socket網路編程
到linux下去學會很快學會的.
因為WINDOWS下的編程工具如:C++BUILDER,VC,VC++
等對SOCKET進行了很好的封裝,
這使得你只需要調用它提供的介面就能完成需要的
讀寫SOCKET的功能,這樣你就不能學到SOCKET的很多
操作函數的使用.
⑵ 如何利用Socket進行網路編程
Socket介面是TCP/IP網路的API,Socket介面定義了許多函數或常式,程序員可以用它們來開發TCP/IP網路上的應用程序。請參閱以下資料:socket非常類似於電話插座。以一個國家級電話網為例。電話的通話雙方相當於相互通信的 個進程,區號是它的網路地址;區內一個單位的交換機相當於一台主機,主機分配給每個用戶的局內號碼相當於socket號。任何用戶在通話之前,首先要佔有一部電話機,相當於申請一個socket;同時要知道對方的號碼,相當於對方有一個固定的socket。然後向對方撥號呼叫,相當於發出連接請求(假如對方不在同一區內,還要撥對方區號,相當於給出網路地址)。對方假如在場並空閑(相當於通信的另一主機開機且可以接受連接請求),拿起電話話筒,雙方就可以正式通話,相當於連接成功。雙方通話的過程,是一方向電話機發出信號和對方從電話機接收信號的過程,相當於向socket發送數據和從socket接收數據。通話結束後,一方掛起電話機相當於關閉socket,撤消連接。在電話系統中,一般用戶只能感受到本地電話機和對方電話號碼的存在,建立通話的過程,話音傳輸的過程以及整個電話系統的技術細節對他都是透明的,這也與socket機制非常相似。socket利用網間網通信設施實現進程通信,但它對通信設施的細節毫不關心,只要通信設施能提供足夠的通信能力,它就滿足了。至此,我們對socket進行了直觀的描述。抽象出來,socket實質上提供了進程通信的端點。進程通信之前,雙方首先必須各自創建一個端點,否則是沒有法建立聯系並相互通信的。正如打電話之前,雙方必須各自擁有一台電話機一樣。在網間網內部,每一個socket用一個半相關描述:(協議,本地地址,本地埠)一個完整的socket有一個本地唯一的socket號,由操作系統分配。最重要的是,socket是面向客戶/伺服器模型而設計的,針對客戶和伺服器程序提供不同的socket系統調用。客戶隨機申請一個socket(相當於一個想打電話的人可以在任何一台入網電話上撥號呼叫),系統為之分配一個socket號;伺服器擁有全局公認的socket,任何客戶都可以向它發出連接請求和信息請求(相當於一個被呼叫的電話擁有一個呼叫方知道的電話號碼)。socket利用客戶/伺服器模式巧妙地解決了進程之間建立通信連接的問題。伺服器socket半相關為全局所公認非常重要。讀者不妨考慮一下,兩個完全隨機的用戶進程之間如何建立通信?假如通信雙方沒有任何一方的socket固定,就好比打電話的雙方彼此不知道對方的電話號碼,要通話是不可能的。實際應用中socket例子Socket介面是訪問Internet使用得最廣泛的方法。如果你有一台剛配好TCP/IP協議的主機,其IP地址是 . . . ,此時在另一台主機或同一台主機上執行ftp . . . ,顯然無法建立連接。因" . . . "這台主機沒有運行FTP服務軟體。同樣,在另一台或同一台主機上運行瀏覽軟體如Netscape,輸入"http:// . . . ",也無法建立連接。現在,如果在這台主機上運行一個FTP服務軟體(該軟體將打開一個Socket,並將其綁定到 埠),再在這台主機上運行一個Web服務軟體(該軟體將打開另一個Socket,並將其綁定到 埠)。這樣,在另一台主機或同一台主機上執行ftp . . . ,FTP客戶軟體將通過 埠來呼叫主機上由FTP服務軟體提供的Socket,與其建立連接並對話。而在netscape中輸入"http:// . . . "時,將通過 埠來呼叫主機上由Web服務軟體提供的Socket,與其建立連接並對話。在Internet上有很多這樣的主機,這些主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都打開一個Socket,並綁定到一個埠上,不同的埠對應於不同的服務。Socket正如其英文原意那樣,象一個多孔插座。一台主機猶如布滿各種插座的房間,每個插座有一個編號,有的插座提供 伏交流電,有的提供 伏交流電,有的則提供有線電視節目。客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。一個Server-Client模型程序的開發原理:伺服器,使用ServerSocket監聽指定的埠,埠可以隨意指定(由於 以下的埠通常屬於保留埠,在一些操作系統中不可以隨意使用,所以建議使用大於 的埠),等待客戶連接請求,客戶連接後,會話產生;在完成會話後,關閉連接。客戶端,使用Socket對網路上某一個伺服器的某一個埠發出連接請求,一旦連接成功,打開會話;會話完成後,關閉Socket。客戶端不需要指定打開的埠,通常臨時的、動態的分配一個 以上的埠。Socket介面是TCP/IP網路的API,Socket介面定義了許多函數或常式,程序員可以用它們來開發TCP/IP網路上的應用程序。要學Internet上的TCP/IP網路編程,必須理解Socket介面。Socket介面設計者最先是將介面放在Unix操作系統裡面的。如果了解Unix系統的輸入和輸出的話,就很容易了解Socket了。網路的Socket數據傳輸是一種特殊的I/O,Socket也是一種文件描述符。Socket也具有一個類似於打開文件的函數調用Socket(),該函數返回一個整型的Socket描述符,隨後的連接建立、數據傳輸等操作都是通過該Socket實現的。常用的Socket類型有兩種:流式Socket(SOCK_STREAM)和數據報式Socket(SOCK_DGRAM)。流式是一種面向連接的Socket,針對於面向連接的TCP服務應用;數據報式Socket是一種無連接的Socket,對應於無連接的UDP服務應用。Socket建立為了建立Socket,程序可以調用Socket函數,該函數返回一個類似於文件描述符的句柄。socket函數原型為:intsocket(intdomain,inttype,intprotocol);domain指明所使用的協議族,通常為PF_INET,表示互聯網協議族(TCP/IP協議族);type參數指定socket的類型:SOCK_STREAM或SOCK_DGRAM,Socket介面還定義了原始Socket(SOCK_RAW),允許程序使用低層協議;protocol通常賦值" "。Socket()調用返回一個整型socket描述符,你可以在後面的調用使用它。Socket描述符是一個指向內部數據結構的指針,它指向描述符表入口。調用Socket函數時,socket執行體將建立一個Socket,實際上"建立一個Socket"意味著為一個Socket數據結構分配存儲空間。Socket執行體為你管理描述符表。兩個網路程序之間的一個網路連接包括五種信息:通信協議、本地協議地址、本地主機埠、遠端主機地址和遠端協議埠。Socket數據結構中包含這五種信息。socket在測量軟體中的使用也很廣泛socket深層次理解Socket編程基本就是listen,accept以及send,write等幾個基本的操作。對於網路編程,我們也言必稱TCP/IP,似乎其它網路協議已經不存在了。對於TCP/IP,我們還知道TCP和UDP,前者可以保證數據的正確和可靠性,後者則允許數據丟失。最後,我們還知道,在建立連接前,必須知道對方的IP地址和埠號。除此,普通的程序員就不會知道太多了,很多時候這些知識已經夠用了。最多,寫服務程序的時候,會使用多線程來處理並發訪問。我們還知道如下幾個事實: 。一個指定的埠號不能被多個程序共用。比如,如果IIS佔用了 埠,那麼Apache就不能也用 埠了。 。很多防火牆只允許特定目標埠的數據包通過。 。服務程序在listen某個埠並accept某個連接請求後,會生成一個新的socket來對該請求進行處理。於是,一個困惑了我很久的問題就產生了。如果一個socket創建後並與 埠綁定後,是否就意味著該socket佔用了 埠呢?如果是這樣的,那麼當其accept一個請求後,生成的新的socket到底使用的是什麼埠呢(我一直以為系統會默認給其分配一個空閑的埠號)?如果是一個空閑的埠,那一定不是 埠了,於是以後的TCP數據包的目標埠就不是 了--防火牆一定會組織其通過的!實際上,我們可以看到,防火牆並沒有阻止這樣的連接,而且這是最常見的連接請求和處理方式。我的不解就是,為什麼防火牆沒有阻止這樣的連接?它是如何判定那條連接是因為connet 埠而生成的?是不是TCP數據包里有什麼特別的標志?或者防火牆記住了什麼東西?後來,我又仔細研讀了TCP/IP的協議棧的原理,對很多概念有了更深刻的認識。比如,在TCP和UDP同屬於傳輸層,共同架設在IP層(網路層)之上。而IP層主要負責的是在節點之間(EndtoEnd)的數據包傳送,這里的節點是一台網路設備,比如計算機。因為IP層只負責把數據送到節點,而不能區分上面的不同應用,所以TCP和UDP協議在其基礎上加入了埠的信息,埠於是標識的是一個節點上的一個應用。除了增加埠信息,UPD協議基本就沒有對IP層的數據進行任何的處理了。而TCP協議還加入了更加復雜的傳輸控制,比如滑動的數據發送窗口(SliceWindow),以及接收確認和重發機制,以達到數據的可靠傳送。不管應用層看到的是怎樣一個穩定的TCP數據流,下面傳送的都是一個個的IP數據包,需要由TCP協議來進行數據重組。所以,我有理由懷疑,防火牆並沒有足夠的信息判斷TCP數據包的信息,除了IP地址和埠號。而且,我們也看到,所謂的埠,是為了區分不同的應用的,以在不同的IP包來到的時候能夠正確轉發。TCP/IP只是一個協議棧,就像操作系統的運行機制一樣,必須要具體實現,同時還要提供對外的操作介面。就像操作系統會提供標準的編程介面,比如Win 編程介面一樣,TCP/IP也必須對外提供編程介面,這就是Socket編程介面--原來是這么回事啊!在Socket編程介面里,設計者提出了一個很重要的概念,那就是socket。這個socket跟文件句柄很相似,實際上在BSD系統里就是跟文件句柄一樣存放在一樣的進程句柄表裡。這個socket其實是一個序號,表示其在句柄表中的位置。這一點,我們已經見過很多了,比如文件句柄,窗口句柄等等。這些句柄,其實是代表了系統中的某些特定的對象,用於在各種函數中作為參數傳入,以對特定的對象進行操作--這其實是C語言的問題,在C++語言里,這個句柄其實就是this指針,實際就是對象指針啦。現在我們知道,socket跟TCP/IP並沒有必然的聯系。Socket編程介面在設計的時候,就希望也能適應其他的網路協議。所以,socket的出現只是可以更方便的使用TCP/IP協議棧而已,其對TCP/IP進行了抽象,形成了幾個最基本的函數介面。比如create,listen,accept,connect,read和write等等。現在我們明白,如果一個程序創建了一個socket,並讓其監聽 埠,其實是向TCP/IP協議棧聲明了其對 埠的佔有。以後,所有目標是 埠的TCP數據包都會轉發給該程序(這里的程序,因為使用的是Socket編程介面,所以首先由Socket層來處理)。所謂accept函數,其實抽象的是TCP的連接建立過程。accept函數返回的新socket其實指代的是本次創建的連接,而一個連接是包括兩部分信息的,一個是源IP和源埠,另一個是宿IP和宿埠。所以,accept可以產生多個不同的socket,而這些socket里包含的宿IP和宿埠是不變的,變化的只是源IP和源埠。這樣的話,這些socket宿埠就可以都是 ,而Socket層還是能根據源/宿對來准確地分辨出IP包和socket的歸屬關系,從而完成對TCP/IP協議的操作封裝!而同時,放火牆的對IP包的處理規則也是清晰明了,不存在前面設想的種種復雜的情形。
⑶ socket網路編程
伺服器與每一個客戶端建立連接,就多了一個線程,通過對線程的名字和Socket對象來進行處理,保存到hasmap.寫一個遍歷hasmap可以得到每個客服的Socket,這樣就可以發送到各個客服端了!
⑷ 在windows下用C語言如何實現socket網路編程,需要用到哪些頭文件或者庫
需要用到的頭文件包含:
#include <winsock2.h>
#include <windows.h>
與Linux環境下socket編程相比,windows環境多了一個步驟:啟動或者初始化winsock庫
Winsock,一種標准API,一種網路編程介面,用於兩個或多個應用程序(或進程)之間通過網路進行數據通信。具有兩個版本:
Winsock 1:
Windows CE平台支持。
頭文件:WinSock.h
庫:wsock32.lib
Winsock 2:
部分平台如Windows CE貌似不支持。通過前綴WSA可以區別於Winsock 1版本。個別函數如WSAStartup、WSACleanup、WSARecvEx、WSAGetLastError都屬於Winsock 1.1規范的函數;
頭文件:WinSock2.h
庫:ws2_32.lib
mswsock.h用於編程擴展,使用時必須鏈接mswsock.dll
(4)sockets網路編程擴展閱讀
winsock庫的載入與卸載:
載入:int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
載入成功,返回值為0。
WORD wVersionRequested:載入的winsock版本,使用宏MAKEWORD(x, y),x表示高位元組,y表示低位元組。然而使用時MAKEWORD(2, 2)。高位元組與低位元組相同~~
LPWSADATA lpWSAData:WSADATA結構的指針,傳入參數後,系統幫助我們填充版本信息。有興趣的可以看看結構體內容,不過基本用不著。
卸載:int WSACleanup(void);比起載入,卸載的函數真是輕松愉快。
⑸ socket網路編程
bzero() 函數的功能是將一塊內存清零。
bzero((char *) sendpkt, sizeof (struct udprecord)); 功能是將 sendpkt 指向的內存清零。
和 memset(sendpkt, 0, sizeof(struct udpprecord)); 的功能是一樣的。
⑹ C# SOCKET網路編程
1. 把 lisThd.ApartmentState = ApartmentState.STA; 注釋掉,ApartmentState 已過時。2. 如果使用TCP協議,建議你使用 TcpListener 類和 TcpClient 類,更加方便。以下是一個示例以下示例說明如何設置 TcpClient 以連接到 TCP 埠 13 上的時間伺服器。
using System;
using System.Net.Sockets;
using System.Text;public class TcpTimeClient {
private const int portNum = 13;
private const string hostName = "host.contoso.com"; public static int Main(String[] args) {
try {
TcpClient client = new TcpClient(hostName, portNum); NetworkStream ns = client.GetStream();
byte[] bytes = new byte[1024];
int bytesRead = ns.Read(bytes, 0, bytes.Length); Console.WriteLine(Encoding.ASCII.GetString(bytes,0,bytesRead)); client.Close(); } catch (Exception e) {
Console.WriteLine(e.ToString());
} return 0;
}
}
TcpListener 用於監視 TCP 埠上的傳入請求,然後創建一個 Socket 或 TcpClient 來管理與客戶端的連接。Start 方法啟用偵聽,而 Stop 方法禁用埠上的偵聽。AcceptTcpClient 方法接受傳入的連接請求並創建 TcpClient 以處理請求,AcceptSocket 方法接受傳入的連接請求並創建 Socket 以處理請求。以下示例說明如何使用 TcpListener 創建網路時間伺服器以監視 TCP 埠 13。當接受傳入的連接請求時,時間伺服器用來自宿主伺服器的當前日期和時間進行響應。using System;
using System.Net.Sockets;
using System.Text;public class TcpTimeServer { private const int portNum = 13; public static int Main(String[] args) {
bool done = false;
TcpListener listener = new TcpListener(portNum); listener.Start(); while (!done) {
Console.Write("Waiting for connection...");
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Connection accepted.");
NetworkStream ns = client.GetStream(); byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString()); try {
ns.Write(byteTime, 0, byteTime.Length);
ns.Close();
client.Close();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
} listener.Stop(); return 0;
}
}
⑺ linux socket網路編程怎樣收發包
1.send函數
ssize_t send( SOCKET s, const char *buf, size_t len, int flags );
(1)send先比較待發送數據的長度len和套接字s的發送緩沖的長度, 如果len大於s的發送緩沖區的長度,該函數返回SOCKET_ERROR;
(2)如果len小於或者等於s的發送緩沖區的長度,那麼send先檢查協議是否正在發送s的發送緩沖中的數據,如果是就等待協議把數據發送完,如果協議還沒有開始發送s的發送緩沖中的數據或者s的發送緩沖中沒有數據,那麼send就比較s的發送緩沖區的剩餘空間和len;
(3)如果len大於剩餘空間大小,send就一直等待協議把s的發送緩沖中的數據發送完;
(4)如果len小於剩餘空間大小,send就僅僅把buf中的數據到剩餘空間里(注意並不是send把s的發送緩沖中的數據傳到連接的另一端的,而是協議傳送的,send僅僅是把buf中的數據到s的發送緩沖區的剩餘空間里)。
注意:
(1)如果send函數數據成功,就返回實際的位元組數,如果send在數據時出現錯誤,那麼send就返回SOCKET_ERROR;如果send在等待協議傳送數據時網路斷開的話,那麼send函數也返回SOCKET_ERROR。
(2)要注意send函數把buf中的數據成功到s的發送緩沖的剩餘空間里後它就返回了,但是此時這些數據並不一定馬上被傳到連接的另一端。如果協議在後續的傳送過程中出現網路錯誤的話,那麼下一個Socket函數就會返回SOCKET_ERROR。(每一個除send外的Socket函數在執行的最開始總要先等待套接字的發送緩沖中的數據被協議傳送完畢才能繼續,如果在等待時出現網路錯誤,那麼該Socket函數就返回 SOCKET_ERROR)
(3)在Unix系統下,如果send在等待協議傳送數據時網路斷開的話,調用send的進程會接收到一個SIGPIPE信號,進程對該信號的默認處理是進程終止。
2.recv函數
ssize_t recv(int s, char *buf, size_t len, int flags);
(1)recv先等待s的發送緩沖中的數據被協議傳送完畢,如果協議在傳送s的發送緩沖
中的數據時出現網路錯誤,那麼recv函數返回SOCKET_ERROR。
(2)如果s的發送緩沖中沒有數據或者數據被協議成功發送完畢後,recv先檢查套接字s的接收緩沖區,如果s接收緩沖區中沒有數據或者協議正在接收數 據,那麼recv就一直等待,直到協議把數據接收完畢。當協議把數據接收完畢,recv函數就把s的接收緩沖中的數據到buf中。(注意:協議接收到的數據可能大於buf的長度,所以 在這種情況下要調用幾次recv函數才能把s的接收緩沖中的數據完。recv函數僅僅是數據,真正的接收數據是協議來完成的)
(3)recv函數返回其實際的位元組數。如果recv在時出錯,那麼它返回SOCKET_ERROR;如果recv函數在等待協議接收數據時網路中斷了,那麼它返回0。
注意:在Unix系統下,如果recv函數在等待協議接收數據時網路斷開了,那麼調用recv的進程會接收到一個SIGPIPE信號,進程對該信號的默認處理是進程終止。
Q&A:
(1)兩次send一次recv會發生什麼?
一次性讀取兩次send的內容。
(2)recv之後,接收緩沖區會被清空嗎?
是的。
⑻ java Socket網路編程
調用 outt.flush ();
⑼ 什麼是socket網路編程
使用socket套接字,利用TCP/IP或者UDP協議,實現幾個機器之間的通信。一般使用C/S結構。
以TCP/IP為例:首先建立一個伺服器,步驟如下:socket()創建一個socket,bind()綁定socket到一個埠,listen()監聽埠,accept()等待客戶端的連接。客戶端程序:socket()創建一個socket,可以綁定也可以不綁定,然後connect()連接到伺服器端。socket又分為阻塞式的和非阻塞式的。阻塞式的就是伺服器端等待連接直到連接上,不然一直掛起。