1. Windows下C語言網路編程快速入門。
C語言的學習,一般的方式是,先學C,然後是C++,最好還要有匯編語言和微機原理基礎,然後才是Visual
C++。這樣的方式,對學習者來說,要花費很多時間和耐力。而在學校教學中,也沒有時間深入學習Windows編程的實用技術了。其實,具有了C語言基礎後,再有一些基本的C++類的概念,就可以直接學習Windows
C編程了。一、走近Windows
C語言很多語言都把顯示一個「Hello,World!」做為第一個入門程序,
C語言的第一個程序是這樣的:#include<stdio.h>
main()
{
printf(「Hello,World!」);
}如果把main函數寫成帶參數的main函數,應該是:#include<stdio.h>
main(int
arge,char
*argv[])
{
printf(「Hello,World!」);
}Windows
C的第一個程序和這個程序在形式和原理上都是一致的,只是有兩點不同:1.
主函數接收的形參不只是命令行中的字元串的個數和字元串的首地址。2.
C語言的很多函數在Windows
C中都可以繼續使用,但象printf()屏幕顯示等函數就不能繼續使用了。因為Windows是多任務操作系統,屏幕已不再為某一個應用程序所獨有,Windows
C應用程序要顯示字元串,需要使用Windows提供的API函數,開自己的窗口下面是一個最簡單的,顯示「Hello,World!」的Windows
C程序:#include<windows.h>
APIENTRY
WinMain(HINSTANCE
hInstance,HINSTANCE
hPrevInstance,
LPSTR
lpCmdLine,int
nCmdShow)
{
MessageBox(NULL,"Hello,World!","第一個Windows
C程序",MB_OK|MB_ICONASTERISK);
}主函數的形參有四個:1)
Hinstance:接收程序運行時當前實例的句柄;2)
HprivInstance:前一個實例的句柄;3)
LpCmdLine:程序命令行指針;4)
NcmdShow:一個用來指定窗口顯示方式的整數。這幾個參數的使用我們會在深入的學習中介紹的。顯示Hello,Word!字元串,我們使用了一個MessageBox函數,這個函數會在屏幕上顯示一個對話框,它的原型是:int
MessageBox(HWND
hWnd,LPCTSTR
lpText,LPCTSTR
lpCaption,UNIT
uType)四個參數分別是:1)
HWnd:父窗口的句柄;2)
LpText:要顯示字元串的指針;3)
LpCaption:對話框標題字元串的指針;4)
UType:顯示在對話框上的小圖標的類型。使用這個函數要包含windows.h頭文件。調試一下,怎麼樣?窗口上彈出了一個「第一個Windows
C程序」對話框,上面有一行字:「Hello,World!」。世界真的很美好啊!!
你連答案也發啦,暈!
2. 怎樣學習Windows 網路編程
新手必學:windows網路編程經典入門
作者:huyoo
對於一個windows網路編程初學者,下面方法是經典入門。
初學者建議不要用MFC提供的類,而用windows API做一個簡單伺服器和客戶端,這樣有助於對socket編程機制的理解。
為了簡單起見,應用程序是基於MFC的標准對話框。
Winsock用WINDOWS API實現:
(1)伺服器端有兩個線程:
主線程 — 你需要編寫以下函數來實現
#define NETWORK_EVENT USER_MESSAGE+100 file://定義網路事件
sockaddr_in clientaddr; file://暫時存放客戶端IP地址
file://自己定義消息映射函數,將上面定義的網路事件映射到處理函數
file://OnNetEvent為網路事件處理函數,它在下面定義
ON_MESSAGE(NETWORK_EVENT, OnNetEvent);
在你對話框中的初始化函數中調用下面的初始化網路的子函數
BOOL InitNetwork() file://初始化網路
{
file://初始化TCP協議
BOOL ret = WSAStartup(MAKEWORD(2,2), &wsaData);
if(ret != 0)
{
MessageBox("初始化套接字失敗!");
return FALSE;
}
file://創建伺服器端套接字
SOCKET serverSocket
= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(serverSocket == INVALID_SOCKET)
{
MessageBox("創建套接字失敗!");
closesocket(m_Socket);
WSACleanup();
return FALSE;
}
file://綁定到本地一個埠上
sockaddr_in localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(1688);
localaddr.sin_addr.s_addr = 0;
if(bind(serverSocket ,(const struct sockaddr*)&localaddr,
sizeof(sockaddr)) == SOCKET_ERROR)
{
MessageBox("綁定地址失敗!");
closesocket(m_Socket);
WSACleanup();
return FALSE;
}
file://注冊網路非同步事件,m_hWnd為應用程序的主對話框或主窗口的句柄
WSAAsyncSelect(serverSocket, m_hWnd, NETWORK_EVENT,
FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE);
listen(serverSocket, 5); file://設置偵聽模式
return TRUE;
}
file://定義網路事件的響應函數
void OnNetEvent(WPARAM wParam, LPARAM lParam)
{
file://調用API函數,得到網路事件類型
int iEvent = WSAGETSELECTEVENT(lParam);
file://得到發出此事件的客戶端套接字
SOCKET pSock = (SOCKET)wParam;
switch(iEvent)
{
case FD_ACCEPT: file://客戶端連接請求
{
OnAccept();
break;
}
case FD_CLOSE: file://客戶端斷開事件:
{
OnClose(pSock);
break;
}
case FD_READ: file://網路數據包到達事件
{
OnReceive(pSock);
break;
}
case FD_WRITE: file://發送網路數據事件
{
OnSend(pSock);
break;
}
default: break;
}
}
void OnAccept(SOCET pSock) file://響應客戶端連接請求函數
{
int len = sizeof(sockaddr);
file://調用API函數,接受連接,並返回一個新套接字
file://還可以獲得客戶端的IP地址
SOCKET clientSocket = accept(serverSocket,
(struct sockaddr*)&clientaddr, &len);
file://為新的socket注冊非同步事件,注意沒有Accept事件
if(WSAAsyncSelect(clientSocket ,m_hWnd, IP_EVENT,
FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
{
MessageBox("注冊非同步事件失敗!");
return;
}
file://自編函數,將此客戶端的相關信息保存下來:套接字、
// IP地址、登陸時間
saveClientSocket(clientSocket,clientAddr,currentTimer);
}
void OnClose(SOCET pSock)
{
file://自編函數,結束與相應的客戶端的通信,釋放相應資源並做相應處理
endClientSocket(pSock);
}
void OnSend(SOCET pSock)
{
file://自編函數,在給客戶端發數據時做一些預處理
handleOnSend(pSock);
}
void OnReceive(SOCET pSock)
{
recv(...); file://調用API函數,讀出網路緩沖區中的數據包
file://自編函數,將此數據包和發出此數據的客戶端
file://clientSocket封裝成一條網路消息
buildNetMsg(...);
file://自編函數,將此網路消息放入一個消息隊列中,由工作線程去處理
saveNetMsg(...);
SetEvent(...); file://用事件對象觸發工作線程
}
客戶端登陸後,隨即把自己的計算機名發給伺服器,伺服器接到後,把它保存下來。這樣伺服器就可以顯示所有在線客戶端的信息了,包括:客戶端計算機名、IP地址、登陸時間等。
注意: 客戶端沒有OnAccept()函數,但有OnConnect()函數。
工作線程 —
在你的應用程序初始化時,創建並啟動一個工作線程
AfxBeginThread(WorkThread,this,THREAD_PRIORITY_NORMAL);
file://this可能為應用程序的主對話框或主窗口的句柄
UINT WorkThread(LPVOID pParam)
{
while(1)
{
file://等待多重事件到來
int ret = WaitForMultipleObject(...);
switch(ret)
{
case OBJECT_0:
{
if(bNewNetMsg) file://查看網路消息隊列是否有新的網路消息
{
readNetMsg(...); file://如有新的網路消息,則讀出
handleNetMsg(...); file://處理此網路消息
}
break;
}
case OBJECT_0 + 1:
{
file://做退出處理
break;
}
default: break;
}
return 0;
}
客戶端為單線程,登陸伺服器時,用connect()函數給伺服器發連接請求;
客戶端沒有OnAccept()函數,但有OnConnect()函數。
在OnConnect()函數里做發連接請求時的預處理;
在OnReceive()函數里響應並處理網路數據;
在OnClose()函數里響應伺服器的關閉事件;
在OnSend()函數里做發數據時的預處理;
如果你還想實現各客戶端之間的在線交流(即所謂的聊天室),你在客戶端還可以基於UDP協議
再做一套多點對多點的區域網組播模型模型,以後在和你聊,你先把上面的程序實現。
以上的I/O非同步模型基於Windows的消息機制,另外還可以用事件模型、重疊模型或完成埠模型,
建議你參考Windows網路編程指南之類的書。
如果你能對上面的機制很熟練,你肯定已經對Winsock編網路程序的機制有一定理解,接下來你可以進行更精彩的編程, 不僅可以在網上傳輸普通數據,而且還
以傳輸語音、視頻數據,你還可以自己做一個聊天室,和你的同學在實驗室的區域網里可以共同分享你的成果。
3. Windows網路編程中 UDP通信問題
在VC中進行WINSOCK的API編程開發的時候,需要在項目中使用下面三個文件,否則會出現編譯錯誤。
1.WINSOCK.H: 這是WINSOCK API的頭文件,需要包含在項目中。
2.WSOCK32.LIB: WINSOCK API連接庫文件。在使用中,一定要把它作為項目的非預設的連接庫包含到項目文件中去。
3.WINSOCK.DLL: WINSOCK的動態連接庫,位於WINDOWS的安裝目錄下。
4. 在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)windows網路編程實驗擴展閱讀
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);比起載入,卸載的函數真是輕松愉快。
5. 如何學習網路編程
具體到編程,用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)邏輯思維能力的培養 學程序設計要有一定的邏輯思維能力,「邏思力」的培養要長時間的實踐鍛煉。要想成為一名優秀的程序員,最重要的是掌握編程思想。要做到這一點必須在反復的實踐、觀察、分析、比較、總結中逐漸地積累。因此在學習編程過程中,我們不必等到什麼都完全明白了才去動手實踐,只要明白了大概,就要敢於自己動手去體驗。誰都有第一次。
有些問題只有通過實踐後才能明白,也只有實踐才能把老師和書上的知識變成自己的,高手都是這樣成材的。
6. Windows網路配置的實驗報告怎麼寫啊
IP:202.204.13.35
子網掩碼:255.255.0.0
網關:202.204.13.1
DNS:202.204.12.4
備用DNS:202.204.12.5
報告的話就把設置的步驟一個個些下來就行了
7. 如何使用windows網路編程select
1. select系統調用
select系統調用是用來讓我們的程序監視多個文件描述符的狀態變化的。程序會停在select這里等待,直到被監視的文件描述符有某一個或多個發生了狀態改變。
select()的機制中提供一fd_set的數據結構,實際上是一long類型的數組,每一個數組元素都能與一打開的文件句柄建立聯系,建立聯系的工作由程序員完成,當調用select()時,由內核根據IO狀態修改fd_set的內容,由此來通知執行了select()的進程哪些Socket或文件可讀可寫。
select函數原型:
#include <sys/select.h> #include <sys/time.h>#include <sys/types.h>#include <unistd.h>int select(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, const struct timeval * timeout);
ndfs:select監視的文件句柄數,視進程中打開的文件數而定,一般設為要監視各文件中的最大文件描述符值加1。
readfds:這個文件描述符集合監視文件集中的任何文件是否有數據可讀,當select函數返回的時候,readfds將清除其中不可讀的文件描述符,只留下可讀的文件描述符。
writefds:這個文件描述符集合監視文件集中的任何文件是否有數據可寫,當select函數返回的時候,writefds將清除其中不可寫的文件描述符,只留下可寫的文件描述符。
exceptfds:這個文件集將監視文件集中的任何文件是否發生錯誤,其實,它可用於其他的用途,例如,監視帶外數據OOB,帶外數據使用MSG_OOB標志發送到套接字上。當select函數返回的時候,exceptfds將清除其中的其他文件描述符,只留下標記有OOB數據的文件描述符。
timeout:本次select()的超時結束時間。這個參數至關重要,它可以使select處於三種狀態:
(1)若將NULL以形參傳入,即不傳入時間結構,就是將select置於阻塞狀態,一定等到監視文件描述符集合中某個文件描述符發生變化為止;
(2)若將時間值設為0秒0毫秒,就變成一個純粹的非阻塞函數,不管文件描述符是否有變化,都立刻返回繼續執行,文件無變化返回0,有變化返回一個正值;
(3)timeout的值大於0,這就是等待的超時時間,即select在timeout時間內阻塞,超時時間之內有事件到來就返回了,否則在超時後不管怎樣一定返回,返回值同上述。
函數的返回值:
正值:表示監視的文件集中有文件描述符符合要求
零值:表示select監視超時
負值:表示發生了錯誤,錯誤值由errno指定。
宏操作:
FD_ZERO(fd_set *set): 用來清除描述片語set的全部位
FD_SET(int fd,fd_set*set): 用來設置描述片語set中相關fd的位
FD_ISSET(int fd,fd_set *set): 用來測試描述片語set中相關fd 的位是否為真
FD_CLR(inr fd,fd_set* set): 用來清除描述片語set中相關fd 的位注意事項:
(1)對於可寫性的檢查,最好放在需要寫數據的時候進行檢查。如果和可讀性放在同一個地方進行檢查,那麼select很可能每次都會因為可寫性檢查成功而返回。
(2)select()調用會清空傳遞給它的集合參數中的內容,也就是會清空readfds、writefd、exceptfds這三個指針參數所指定的描述符集合。因此,在每次調用select()之前,必須重新初始化並把需要監視的描述符填寫到相應的描述符集合中。select()調用也會清空timeout指針所指向的struct timeval結構,所以在每次調用select()之前也要重新填充timeout指針所指向的struct timeval結構。
8. 如何利用Windows Sockets進行網路編程
Socket實際在計算機中提供了一個通信埠,可以通過這個埠與任何一個具有Socket介面的計算機通信。應用程序在網路上傳輸,接收的信息都通過這個Socket介面來實現。
9. windows網路編程作業,如何用VC做一個類似QQ的程序,急求!
socket 通信,傳輸文字就可以了
10. 在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庫就可以了。