導航:首頁 > 編程語言 > socket編程指南

socket編程指南

發布時間:2022-12-13 14:27:45

① 如何學習socket網路編程

到LINUX下去學會很快學會的.

因為WINDOWS下的編程工具如:C++BUILDER,VC,VC++
等對SOCKET進行了很好的封裝,
這使得你只需要調用它提供的介面就能完成需要的
讀寫SOCKET的功能,這樣你就不能學到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

(2)socket編程指南擴展閱讀

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);比起載入,卸載的函數真是輕松愉快。

③ 網路編程socketserver的方法有哪些

java網路編程精解之ServerSocket用法詳解一

第3章 ServerSocket用法詳解 第10章 Java語言的反射機制 第13章 基於MVC和RMI的分布
ServerSocket用法詳解一
Java語言的反射機制一
基於MVC和RMI的分布式應用一
ServerSocket用法詳解二
Java語言的反射機制二
基於MVC和RMI的分布式應用二
ServerSocket用法詳解三
在客戶/伺服器通信模式中,伺服器端需要創建監聽特定埠的ServerSocket,ServerSocket負責接收客戶連接請求。本章首先介紹ServerSocket類的各個構造方法,以及成員方法的用法,接著介紹伺服器如何用多線程來處理與多個客戶的通信任務。
本章提供線程池的一種實現方式。線程池包括一個工作隊列和若干工作線程。伺服器程序向工作隊列中加入與客戶通信的任務,工作線程不斷從工作隊列中取出任務並執行它。本章還介紹了java.util.concurrent包中的線程池類的用法,在伺服器程序中可以直接使用它們。
3.1 構造ServerSocket
ServerSocket的構造方法有以下幾種重載形式:
◆ServerSocket()throws IOException
◆ServerSocket(int port) throws IOException
◆ServerSocket(int port, int backlog) throws IOException
◆ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException
在以上構造方法中,參數port指定伺服器要綁定的埠(伺服器要監聽的埠),參數backlog指定客戶連接請求隊列的長度,參數bindAddr指定伺服器要綁定的IP地址。
3.1.1 綁定埠
除了第一個不帶參數的構造方法以外,其他構造方法都會使伺服器與特定埠綁定,該埠由參數port指定。例如,以下代碼創建了一個與80埠綁定的伺服器:
ServerSocket serverSocket=new ServerSocket(80);
如果運行時無法綁定到80埠,以上代碼會拋出IOException,更確切地說,是拋出BindException,它是IOException的子類。BindException一般是由以下原因造成的:
◆埠已經被其他伺服器進程佔用;
◆在某些操作系統中,如果沒有以超級用戶的身份來運行伺服器程序,那麼操作系統不允許伺服器綁定到1~1023之間的埠。
如果把參數port設為0,表示由操作系統來為伺服器分配一個任意可用的埠。由操作系統分配的埠也稱為匿名埠。對於多數伺服器,會使用明確的埠,而不會使用匿名埠,因為客戶程序需要事先知道伺服器的埠,才能方便地訪問伺服器。在某些場合,匿名埠有著特殊的用途,本章3.4節會對此作介紹。
3.1.2 設定客戶連接請求隊列的長度
當伺服器進程運行時,可能會同時監聽到多個客戶的連接請求。例如,每當一個客戶進程執行以下代碼:
Socket socket=new Socket(www.javathinker.org,80);
就意味著在遠程www.javathinker.org主機的80埠上,監聽到了一個客戶的連接請求。管理客戶連接請求的任務是由操作系統來完成的。操作系統把這些連接請求存儲在一個先進先出的隊列中。許多操作系統限定了隊列的最大長度,一般為50。當隊列中的連接請求達到了隊列的最大容量時,伺服器進程所在的主機會拒絕新的連接請求。只有當伺服器進程通過ServerSocket的accept()方法從隊列中取出連接請求,使隊列騰出空位時,隊列才能繼續加入新的連接請求。
對於客戶進程,如果它發出的連接請求被加入到伺服器的隊列中,就意味著客戶與伺服器的連接建立成功,客戶進程從Socket構造方法中正常返回。如果客戶進程發出的連接請求被伺服器拒絕,Socket構造方法就會拋出ConnectionException。
ServerSocket構造方法的backlog參數用來顯式設置連接請求隊列的長度,它將覆蓋操作系統限定的隊列的最大長度。值得注意的是,在以下幾種情況中,仍然會採用操作系統限定的隊列的最大長度:
◆backlog參數的值大於操作系統限定的隊列的最大長度;
◆backlog參數的值小於或等於0;
◆在ServerSocket構造方法中沒有設置backlog參數。
以下常式3-1的Client.java和常式3-2的Server.java用來演示伺服器的連接請求隊列的特性。
常式3-1 Client.java
import java.net.*;
public class Client {
public static void main(String args[])throws Exception{
final int length=100;
String host="localhost";
int port=8000;
Socket[] sockets=new Socket[length];
for(int i=0;i<length;i++){ ="" 試圖建立100次連接
sockets[i]=new Socket(host, port);
System.out.println("第"+(i+1)+"次連接成功");
}
Thread.sleep(3000);
for(int i=0;i<length;i++){
sockets[i].close(); //斷開連接
}
}
}
#p#
常式3-2 Server.java
import java.io.*;
import java.net.*;
public class Server {
private int port=8000;
private ServerSocket serverSocket;
public Server() throws IOException {
serverSocket = new ServerSocket(port,3); //連接請求隊列的長度為3
System.out.println("伺服器啟動");
}
public void service() {
while (true) {
Socket socket=null;
try {
socket = serverSocket.accept(); //從連接請求隊列中取出一個
連接
System.out.println("New connection accepted " +
socket.getInetAddress() + ":" +socket.getPort());
}catch (IOException e) {
e.printStackTrace();
}finally {
try{
if(socket!=null)socket.close();
}catch (IOException e) {e.printStackTrace();}
}
}
}
public static void main(String args[])throws Exception {
Server server=new Server();
Thread.sleep(60000*10); //睡眠10分鍾
//server.service();
}
}
Client試圖與Server進行100次連接。在Server類中,把連接請求隊列的長度設為3。這意味著當隊列中有了3個連接請求時,如果Client再請求連接,就會被Server拒絕。下面按照以下步驟運行Server和Client程序。
(1)把Server類的main()方法中的「server.service();」這行程序代碼注釋掉。這使得伺服器與8000埠綁定後,永遠不會執行serverSocket.accept()方法。這意味著隊列中的連接請求永遠不會被取出。先運行Server程序,然後再運行Client程序,Client程序的列印結果如下:
第1次連接成功
第2次連接成功
第3次連接成功
Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.(Unknown Source)
at java.net.Socket.(Unknown Source)
at Client.main(Client.java:10)
從以上列印結果可以看出,Client與Server在成功地建立了3個連接後,就無法再創建其餘的連接了,因為伺服器的隊列已經滿了。
(2)把Server類的main()方法按如下方式修改:
public static void main(String args[])throws Exception {
Server server=new Server();
//Thread.sleep(60000*10); //睡眠10分鍾
server.service();
}
作了以上修改,伺服器與8 000埠綁定後,就會在一個while循環中不斷執行serverSocket.accept()方法,該方法從隊列中取出連接請求,使得隊列能及時騰出空位,以容納新的連接請求。先運行Server程序,然後再運行Client程序,Client程序的列印結果如下:
第1次連接成功
第2次連接成功
第3次連接成功

第100次連接成功
從以上列印結果可以看出,此時Client能順利與Server建立100次連接。
3.1.3 設定綁定的IP地址
如果主機只有一個IP地址,那麼默認情況下,伺服器程序就與該IP地址綁定。ServerSocket的第4個構造方法ServerSocket(int port, int backlog, InetAddress bindAddr)有一個bindAddr參數,它顯式指定伺服器要綁定的IP地址,該構造方法適用於具有多個IP地址的主機。假定一個主機有兩個網卡,一個網卡用於連接到Internet, IP地址為222.67.5.94,還有一個網卡用於連接到本地區域網,IP地址為192.168.3.4。如果伺服器僅僅被本地區域網中的客戶訪問,那麼可以按如下方式創建ServerSocket:
ServerSocket serverSocket=new ServerSocket(8000,10,InetAddress.getByName ("192.168.3.4"));
3.1.4 默認構造方法的作用
ServerSocket有一個不帶參數的默認構造方法。通過該方法創建的ServerSocket不與任何埠綁定,接下來還需要通過bind()方法與特定埠綁定。
這個默認構造方法的用途是,允許伺服器在綁定到特定埠之前,先設置ServerSocket的一些選項。因為一旦伺服器與特定埠綁定,有些選項就不能再改變了。
在以下代碼中,先把ServerSocket的SO_REUSEADDR選項設為true,然後再把它與8000埠綁定:
ServerSocket serverSocket=new ServerSocket();
serverSocket.setReuseAddress(true); //設置ServerSocket的選項
serverSocket.bind(new InetSocketAddress(8000)); //與8000埠綁定
如果把以上程序代碼改為:
ServerSocket serverSocket=new ServerSocket(8000);
serverSocket.setReuseAddress(true); //設置ServerSocket的選項
那麼serverSocket.setReuseAddress(true)方法就不起任何作用了,因為SO_ REUSEADDR選項必須在伺服器綁定埠之前設置才有效。
#p#
3.2 接收和關閉與客戶的連接
ServerSocket的accept()方法從連接請求隊列中取出一個客戶的連接請求,然後創建與客戶連接的Socket對象,並將它返回。如果隊列中沒有連接請求,accept()方法就會一直等待,直到接收到了連接請求才返回。
接下來,伺服器從Socket對象中獲得輸入流和輸出流,就能與客戶交換數據。當伺服器正在進行發送數據的操作時,如果客戶端斷開了連接,那麼伺服器端會拋出一個IOException的子類SocketException異常:
java.net.SocketException: Connection reset by peer
這只是伺服器與單個客戶通信中出現的異常,這種異常應該被捕獲,使得伺服器能繼續與其他客戶通信。
以下程序顯示了單線程伺服器採用的通信流程:
public void service() {
while (true) {
Socket socket=null;
try {
socket = serverSocket.accept(); //從連接請求隊列中取出一個連接
System.out.println("New connection accepted " +
socket.getInetAddress() + ":" +socket.getPort());
//接收和發送數據

}catch (IOException e) {
//這只是與單個客戶通信時遇到的異常,可能是由於客戶端過早斷開連接引起的
//這種異常不應該中斷整個while循環
e.printStackTrace();
}finally {
try{
if(socket!=null)socket.close(); //與一個客戶通信結束後,要關閉
Socket
}catch (IOException e) {e.printStackTrace();}
}
}
}
與單個客戶通信的代碼放在一個try代碼塊中,如果遇到異常,該異常被catch代碼塊捕獲。try代碼塊後面還有一個finally代碼塊,它保證不管與客戶通信正常結束還是異常結束,最後都會關閉Socket,斷開與這個客戶的連接。
3.3 關閉ServerSocket
ServerSocket的close()方法使伺服器釋放佔用的埠,並且斷開與所有客戶的連接。當一個伺服器程序運行結束時,即使沒有執行ServerSocket的close()方法,操作系統也會釋放這個伺服器佔用的埠。因此,伺服器程序並不一定要在結束之前執行ServerSocket的close()方法。
在某些情況下,如果希望及時釋放伺服器的埠,以便讓其他程序能佔用該埠,則可以顯式調用ServerSocket的close()方法。例如,以下代碼用於掃描1~65535之間的埠號。如果ServerSocket成功創建,意味著該埠未被其他伺服器進程綁定,否者說明該埠已經被其他進程佔用:
for(int port=1;port<=65535;port++){
try{
ServerSocket serverSocket=new ServerSocket(port);
serverSocket.close(); //及時關閉ServerSocket
}catch(IOException e){
System.out.println("埠"+port+" 已經被其他伺服器進程佔用");
}
}
以上程序代碼創建了一個ServerSocket對象後,就馬上關閉它,以便及時釋放它佔用的埠,從而避免程序臨時佔用系統的大多數埠。
ServerSocket的isClosed()方法判斷ServerSocket是否關閉,只有執行了ServerSocket的close()方法,isClosed()方法才返回true;否則,即使ServerSocket還沒有和特定埠綁定,isClosed()方法也會返回false。
ServerSocket的isBound()方法判斷ServerSocket是否已經與一個埠綁定,只要ServerSocket已經與一個埠綁定,即使它已經被關閉,isBound()方法也會返回true。
如果需要確定一個ServerSocket已經與特定埠綁定,並且還沒有被關閉,則可以採用以下方式:
boolean isOpen=serverSocket.isBound() && !serverSocket.isClosed();
3.4 獲取ServerSocket的信息
ServerSocket的以下兩個get方法可分別獲得伺服器綁定的IP地址,以及綁定的埠:
◆public InetAddress getInetAddress()
◆public int getLocalPort()
前面已經講到,在構造ServerSocket時,如果把埠設為0,那麼將由操作系統為伺服器分配一個埠(稱為匿名埠),程序只要調用getLocalPort()方法就能獲知這個埠號。如常式3-3所示的RandomPort創建了一個ServerSocket,它使用的就是匿名埠。
#p#
常式3-3 RandomPort.java
import java.io.*;
import java.net.*;
public class RandomPort{
public static void main(String args[])throws IOException{
ServerSocket serverSocket=new ServerSocket(0);
System.out.println("監聽的埠為:"+serverSocket.getLocalPort());
}
}
多次運行RandomPort程序,可能會得到如下運行結果:
C:\chapter03\classes>java RandomPort
監聽的埠為:3000
C:\chapter03\classes>java RandomPort
監聽的埠為:3004
C:\chapter03\classes>java RandomPort
監聽的埠為:3005
多數伺服器會監聽固定的埠,這樣才便於客戶程序訪問伺服器。匿名埠一般適用於伺服器與客戶之間的臨時通信,通信結束,就斷開連接,並且ServerSocket佔用的臨時埠也被釋放。
FTP(文件傳輸)協議就使用了匿名埠。如圖3-1所示,FTP協議用於在本地文件系統與遠程文件系統之間傳送文件。

圖3-1 FTP協議用於在本地文件系統與遠程文件系統之間傳送文件
FTP使用兩個並行的TCP連接:一個是控制連接,一個是數據連接。控制連接用於在客戶和伺服器之間發送控制信息,如用戶名和口令、改變遠程目錄的命令或上傳和下載文件的命令。數據連接用於傳送文件。TCP伺服器在21埠上監聽控制連接,如果有客戶要求上傳或下載文件,就另外建立一個數據連接,通過它來傳送文件。數據連接的建立有兩種方式。
(1)如圖3-2所示,TCP伺服器在20埠上監聽數據連接,TCP客戶主動請求建立與該埠的連接。

圖3-2 TCP伺服器在20埠上監聽數據連接
(2)如圖3-3所示,首先由TCP客戶創建一個監聽匿名埠的ServerSocket,再把這個ServerSocket監聽的埠號(調用ServerSocket的getLocalPort()方法就能得到埠號)發送給TCP伺服器,然後由TCP伺服器主動請求建立與客戶端的連接。

圖3-3 TCP客戶在匿名埠上監聽數據連接
以上第二種方式就使用了匿名埠,並且是在客戶端使用的,用於和伺服器建立臨時的數據連接。在實際應用中,在伺服器端也可以使用匿名埠。
3.5 ServerSocket選項
ServerSocket有以下3個選項。
◆SO_TIMEOUT:表示等待客戶連接的超時時間。
◆SO_REUSEADDR:表示是否允許重用伺服器所綁定的地址。
◆SO_RCVBUF:表示接收數據的緩沖區的大小。
3.5.1 SO_TIMEOUT選項
◆設置該選項:public void setSoTimeout(int timeout) throws SocketException
◆讀取該選項:public int getSoTimeout () throws IOException
SO_TIMEOUT表示ServerSocket的accept()方法等待客戶連接的超時時間,以毫秒為單位。如果SO_TIMEOUT的值為0,表示永遠不會超時,這是SO_TIMEOUT的默認值。
當伺服器執行ServerSocket的accept()方法時,如果連接請求隊列為空,伺服器就會一直等待,直到接收到了客戶連接才從accept()方法返回。如果設定了超時時間,那麼當伺服器等待的時間超過了超時時間,就會拋出SocketTimeoutException,它是InterruptedException的子類。
如常式3-4所示的TimeoutTester把超時時間設為6秒鍾。
#p#
常式3-4 TimeoutTester.java
import java.io.*;
import java.net.*;
public class TimeoutTester{
public static void main(String args[])throws IOException{
ServerSocket serverSocket=new ServerSocket(8000);
serverSocket.setSoTimeout(6000); //等待客戶連接的時間不超過6秒
Socket socket=serverSocket.accept();
socket.close();
System.out.println("伺服器關閉");
}
}
運行以上程序,過6秒鍾後,程序會從serverSocket.accept()方法中拋出Socket- TimeoutException:
C:\chapter03\classes>java TimeoutTester
Exception in thread "main" java.net.SocketTimeoutException: Accept timed out
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(Unknown Source)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at TimeoutTester.main(TimeoutTester.java:8)
如果把程序中的「serverSocket.setSoTimeout(6000)」注釋掉,那麼serverSocket. accept()方法永遠不會超時,它會一直等待下去,直到接收到了客戶的連接,才會從accept()方法返回。
Tips:伺服器執行serverSocket.accept()方法時,等待客戶連接的過程也稱為阻塞。本書第4章的4.1節(線程阻塞的概念)詳細介紹了阻塞的概念。
3.5.2 SO_REUSEADDR選項
◆設置該選項:public void setResuseAddress(boolean on) throws SocketException
◆讀取該選項:public boolean getResuseAddress() throws SocketException
這個選項與Socket的SO_REUSEADDR選項相同,用於決定如果網路上仍然有數據向舊的ServerSocket傳輸數據,是否允許新的ServerSocket綁定到與舊的ServerSocket同樣的埠上。SO_REUSEADDR選項的默認值與操作系統有關,在某些操作系統中,允許重用埠,而在某些操作系統中不允許重用埠。
當ServerSocket關閉時,如果網路上還有發送到這個ServerSocket的數據,這個ServerSocket不會立刻釋放本地埠,而是會等待一段時間,確保接收到了網路上發送過來的延遲數據,然後再釋放埠。
許多伺服器程序都使用固定的埠。當伺服器程序關閉後,有可能它的埠還會被佔用一段時間,如果此時立刻在同一個主機上重啟伺服器程序,由於埠已經被佔用,使得伺服器程序無法綁定到該埠,伺服器啟動失敗,並拋出BindException:
Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind
為了確保一個進程關閉了ServerSocket後,即使操作系統還沒釋放埠,同一個主機上的其他進程還可以立刻重用該埠,可以調用ServerSocket的setResuse- Address(true)方法:
if(!serverSocket.getResuseAddress())serverSocket.setResuseAddress(true);
值得注意的是,serverSocket.setResuseAddress(true)方法必須在ServerSocket還沒有綁定到一個本地埠之前調用,否則執行serverSocket.setResuseAddress(true)方法無效。此外,兩個共用同一個埠的進程必須都調用serverSocket.setResuseAddress(true)方法,才能使得一個進程關閉ServerSocket後,另一個進程的ServerSocket還能夠立刻重用相同埠。
3.5.3 SO_RCVBUF選項
◆設置該選項:public void setReceiveBufferSize(int size) throws SocketException
◆讀取該選項:public int getReceiveBufferSize() throws SocketException
SO_RCVBUF表示伺服器端的用於接收數據的緩沖區的大小,以位元組為單位。一般說來,傳輸大的連續的數據塊(基於HTTP或FTP協議的數據傳輸)可以使用較大的緩沖區,這可以減少傳輸數據的次數,從而提高傳輸數據的效率。而對於互動式的通信(Telnet和網路游戲),則應該採用小的緩沖區,確保能及時把小批量的數據發送給對方。
SO_RCVBUF的默認值與操作系統有關。例如,在Windows 2000中運行以下代碼時,顯示SO_RCVBUF的默認值為8192:
ServerSocket serverSocket=new ServerSocket(8000);
System.out.println(serverSocket.getReceiveBufferSize()); //列印8192
無論在ServerSocket綁定到特定埠之前或之後,調用setReceiveBufferSize()方法都有效。例外情況下是如果要設置大於64K的緩沖區,則必須在ServerSocket綁定到特定埠之前進行設置才有效。例如,以下代碼把緩沖區設為128K:
ServerSocket serverSocket=new ServerSocket();
int size=serverSocket.getReceiveBufferSize();
if(size<131072) serverSocket.setReceiveBufferSize(131072); //把緩沖區的大小設為128K
serverSocket.bind(new InetSocketAddress(8000)); //與8 000埠綁定
執行serverSocket.setReceiveBufferSize()方法,相當於對所有由serverSocket.accept()方法返回的Socket設置接收數據的緩沖區的大小。
3.5.4 設定連接時間、延遲和帶寬的相對重要性
◆public void setPerformancePreferences(int connectionTime,int latency,int bandwidth)
該方法的作用與Socket的setPerformancePreferences()方法的作用相同,用於設定連接時間、延遲和帶寬的相對重要性,參見本書第2章的2.5.10節(設定連接時間、延遲和帶寬的相對重要性)。

④ UDP和Socket通信步驟

這是在網上找到的,希望對你有所幫助。
sockets(套接字)編程有三種,流式套接字(SOCK_STREAM),數據報套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);

WINDOWS環境下TCP/UDP編程步驟:

1. 基於TCP的socket編程是採用的流式套接字。

在這個程序中,將兩個工程添加到一個工作區。要鏈接一個ws2_32.lib的庫文件。

伺服器端編程的步驟:

1:載入套接字型檔,創建套接字(WSAStartup()/socket());

2:綁定套接字到一個IP地址和一個埠上(bind());

3:將套接字設置為監聽模式等待連接請求(listen());

4:請求到來後,接受連接請求,返回一個新的對應於此次連接的套接字(accept());

5:用返回的套接字和客戶端進行通信(send()/recv());

6:返回,等待另一連接請求;

7:關閉套接字,關閉載入的套接字型檔(closesocket()/WSACleanup())。

伺服器端代碼如下:

#include <stdio.h>

#include <Winsock2.h>

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) {

return;

}

if ( LOBYTE( wsaData.wVersion ) != 1 ||

HIBYTE( wsaData.wVersion ) != 1 ) {

WSACleanup( );

return;

}

SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

listen(sockSrv,5);

SOCKADDR_IN addrClient;

int len=sizeof(SOCKADDR);

while(1)

{

SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);

char sendBuf[50];

sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));

send(sockConn,sendBuf,strlen(sendBuf)+1,0);

char recvBuf[50];

recv(sockConn,recvBuf,50,0);

printf("%s\n",recvBuf);

closesocket(sockConn);

}

}

客戶端編程的步驟:

1:載入套接字型檔,創建套接字(WSAStartup()/socket());

2:向伺服器發出連接請求(connect());

3:和伺服器端進行通信(send()/recv());

4:關閉套接字,關閉載入的套接字型檔(closesocket()/WSACleanup())。

客戶端的代碼如下:

#include <stdio.h>

#include <Winsock2.h>

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) {

return;

}

if ( LOBYTE( wsaData.wVersion ) != 1 ||

HIBYTE( wsaData.wVersion ) != 1 ) {

WSACleanup( );

return;

}

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

char recvBuf[50];

recv(sockClient,recvBuf,50,0);

printf("%s\n",recvBuf);

send(sockClient,"hello",strlen("hello")+1,0);

closesocket(sockClient);

WSACleanup();

}

2.基於UDP的socket編程是採用的數據報套接字。

在這個程序中,將兩個工程添加到一個工作區。同時還要鏈接一個ws2_32.lib的庫文件。

伺服器端編程的步驟:

1:載入套接字型檔,創建套接字(WSAStartup()/socket());

2:綁定套接字到一個IP地址和一個埠上(bind());

3:等待和接收數據(sendto()/recvfrom());

4:關閉套接字,關閉載入的套接字型檔(closesocket()/WSACleanup())。

伺服器端代碼如下:

#include <winsock2.h>

#include <stdio.h>

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 )

{

return;

}

if ( LOBYTE( wsaData.wVersion ) != 1 ||

HIBYTE( wsaData.wVersion ) != 1 )

{

WSACleanup( );

return;

}

SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(7003);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

char recvBuf[50];

SOCKADDR addrClient;

int len=sizeof(SOCKADDR);

recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)&addrClient,&len);

printf("%s\n",recvBuf);

closesocket(sockSrv);

WSACleanup();

}

對於基於UDP的socket客戶端來說,要進行如下步驟:

1:創建一個套接字(socket);

2:向伺服器發送數據(sendto);

3:關閉套接字;

代碼如下:

#include <winsock2.h>

#include <stdio.h>

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) {

return;

}

if ( LOBYTE( wsaData.wVersion ) != 2 ||

HIBYTE( wsaData.wVersion ) != 2 ) {

WSACleanup( );

return;

}

SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);

SOCKADDR_IN addrClient;

addrClient.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

addrClient.sin_family=AF_INET;

addrClient.sin_port=htons(8889);

SOCKADDR_IN addrSrv;

sendto(sockClient,"hi",3,0,(SOCKADDR*)&addrClient,sizeof(SOCKADDR));

}

LINUX環境下TCP/UDP編程步驟:

TCP編程步驟:

一. 服務端:

1.socket(int domain,int type,int protocol):建立套接字;

2 .bind(int sockid,struct sockaddr *addrp,socklen_t addrlen):把本機地址和埠跟上一步建立的socket綁定在一起;

3.listen(int sockid,int qsize):監聽某套接字;

4.fd=accept(int sockid,struct sockaddr *callerid,socklen_t *addrlenp):等待某套接字接收信息;

5.recv(int fd,void *buf,size_t nbytes,int flags):從套接字接收數據;

6.close(fd) 和close(sockid)

二.客戶端:

1. socket():建立套接字;

2.connect(int sockid,struct sockaddr *serv_addrp,socklen_t addrlen):連接到伺服器;

3. send(int sockfd,const void *buf,size_t nbytes,int flags):發送數據到伺服器.

4. close(sockid);

UDP編程步驟:

一,服務端:

1. socket():同上;

2. bind():同上;

3. recvfrom(int sockfd,void*buff,size_t nbytes,int flags,struct sockaddr*from,socklen_t*addrlen):在套接字口接收數據,並且記錄下接收到的數據來源;一定要注意這里的參數addrlen,它不僅是函數的輸出,也是函數的輸入!所以要在調用該函數之前對addrlen賦值sizeof(struct sockaddr)。否則返回的地址from將會出錯!

4. close(sockfd);

二. 客戶端:

1. socket();同上;

2. sendto(int sockfd,const void*buff,size_t nbytes,int flags,const struct sockaddr*to,socklen_t addrlen):往指定的地址發送數據;

3. close(sockfd);

⑤ C++新手如何學習socket

C++新手學學習socket;
1、先從最簡單的Socket文檔里了解普通的客戶端和服務端工作步驟;
2、再而逐步了解阻塞和非阻塞模式;
3、再繼續理解TCP/IP中的可靠連接和非可靠連接;
4、寫出簡單的客戶端服務端工程,然後接著學習更多的協議,察看<<Windows核心編程>>;
5、最後再學習非同步I/O操作,完成埠的使用方式,進而寫出功能強大的Socket通訊程序。

⑥ 如何學習網路編程

具體到編程,用java來實現網路編程是很容易的,可以作為網路編程的入門。使用C++和winsock相對復雜一些。

總之看實際需要了。
你好初學網路編程者可以從以下幾個步驟開展:
1)下載一個可以互動的學習工具,通過這個與這個工具互動,我們可以及時的學到每個api的結果如果。
對於有c/c++或java基礎的朋友通過一兩個禮拜的時間就可以上手了,另外個人建議初學者可以學習dive into python
2)掌握網路編程中會用到的幾個基本概念和內涵,比如IP地址,port號,socket等
3)記住和消化網路編程C/S模型,把server和client端編程的常用模式理解和消化
4)花幾天時間學習socket api集,api集可以分為下面幾大類:創建 socket bind listen accept收發 read/recv/recvfrom write/send/sendto關閉 close shutdown參數 getsockopt/setsockopt地址 gethostbyaddr getaddrbyhost,...在學習這些api時候,可以先關注在函數功能,參數意義上
5)結合python互動平台,實踐socket api的用法,比如socket函數怎麼使用,bind怎麼使用等等。在互動過程中,我們可以變換參數,看看調用結果如何。比如,創建一個tcp socket的語法如下:socket(AF_INET,SOCK_STREAM)創建一個udp socket的語法如下:socket(AF_INET,SOCK_DGRAM)
6)學習socket server端編程實現簡單規約比如echo,time等,然後通過cmd中的telnet來測試。
7)學習I/O模型,比如阻塞、非阻塞和反應式(select,poll,WaitForMultipleObject)等
8)學習Richard Stevens的《Unix網路編程》,深入學習其中的api原理以及服務端設計原理,並通過代碼編寫。
9)下載高性能網路編程框架twisted,筆者強烈推薦,它將使你的網路編程效率提高10倍以上。
10)學習設計模式、操作系統知識比如線程、進程、同步等。

要想真正掌握計算機技術,並在IT行業里干出一番事業來,有所作為,具有一定的編程能力是一個基本條件和要求。打好基礎學編程要具備一定的基礎,總結之有以下幾方面:
(1)數學基礎 從計算機發展和應用的歷史來看計算機的數學模型和體系結構等都是有數學家提出的,最早的計算機也是為數值計算而設計的。因此,要學好計算機就要有一定的數學基礎,出學者有高中水平就差不多了。
(2)邏輯思維能力的培養 學程序設計要有一定的邏輯思維能力,「邏思力」的培養要長時間的實踐鍛煉。要想成為一名優秀的程序員,最重要的是掌握編程思想。要做到這一點必須在反復的實踐、觀察、分析、比較、總結中逐漸地積累。因此在學習編程過程中,我們不必等到什麼都完全明白了才去動手實踐,只要明白了大概,就要敢於自己動手去體驗。誰都有第一次。

有些問題只有通過實踐後才能明白,也只有實踐才能把老師和書上的知識變成自己的,高手都是這樣成材的。

⑦ 跪求:使用socket進行通信程序設計,編寫一個網路通信應用程序,包括伺服器端和客服端兩個程序。

網路知道里有很多:
http://..com/q?word=socket%CD%A8%D0%C5%CA%B5%CF%D6C%2FS%B3%CC%D0%F2%B5%C4%BB%F9%B1%BE%B7%BD%B7%A8&ct=17&pn=0&tn=ikaslist&rn=10&fr=qrl&cid=93&fr2=query

⑧ 在windows下,如何用純C語言實現socket網路編程

mfc只是對socket進行了一些封裝,大部分人做網路編程都是用的原始的socket,比如如下介面都可以在c下進行調用
1.socket()
2.bind()
3.connect()
4.listen()
5.accept()
6.send() 和recv()
7.sendto() 和recvfrom()
8.close() 和shutdown()
9.getpeername()
10.gethostname()
這些介面是在Winsock2.h中定義的不是在mfc中定義的,你只需要包含Winsock2.h頭文件和Ws2_32.lib庫就可以了。

閱讀全文

與socket編程指南相關的資料

熱點內容
dvd光碟存儲漢子演算法 瀏覽:758
蘋果郵件無法連接伺服器地址 瀏覽:963
phpffmpeg轉碼 瀏覽:672
長沙好玩的解壓項目 瀏覽:145
專屬學情分析報告是什麼app 瀏覽:564
php工程部署 瀏覽:833
android全屏透明 瀏覽:737
阿里雲伺服器已開通怎麼辦 瀏覽:803
光遇為什麼登錄時伺服器已滿 瀏覽:302
PDF分析 瀏覽:486
h3c光纖全工半全工設置命令 瀏覽:143
公司法pdf下載 瀏覽:383
linuxmarkdown 瀏覽:350
華為手機怎麼多選文件夾 瀏覽:683
如何取消命令方塊指令 瀏覽:350
風翼app為什麼進不去了 瀏覽:779
im4java壓縮圖片 瀏覽:362
數據查詢網站源碼 瀏覽:151
伊克塞爾文檔怎麼進行加密 瀏覽:893
app轉賬是什麼 瀏覽:163