【windows socket+TCP伺服器客戶端】
Windows Socket+TCP伺服器客戶端
Winsock是 Windows下套接字標準。
Socket套接字基於計算機網路,提供同一系統上不同程式或由區域網連線在一起的不同機器上的程式間通訊功能。如下圖:
套接字通過IP地址,Port埠號標識,通過這個標識可以在整個區域網定位一個套接字,通過套接字程式便可以相互傳輸資料。如:程式A與程式B之間欲通過套接字通訊,首先程式A建立一個有IP地址,埠號唯一標識的套接字,程式B同樣建立一個有IP地址,埠號唯一標識的套接字,程式A,B便可以通過對方套接字傳送與接收資訊。
TCP提供是可靠的資料傳輸服務,通過TCP套介面函式使用。
1.庫支援:
Winsock
API 函式由WS2_32.DLL支援,可通過WS2_32.LIB訪問。Windows socket程式設計前需要初始化WS2_32.DLL,通過han函式WSAStartup完成初始化。
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") //靜態載入ws2_32.lib
WS2_32.DLL 初始化:
int WSAStartup(WORD wVersionRequested,LPWSADATA
lpWSAData);
該函式第一個引數為WS2_32.DLL版本,通常設為MAKEWORD(2,0),第二個引數為一個指向WSADA他的指標,用於返回WS2_32.DLL的配置資訊。Socket程式設計前需要呼叫該函式。
WS2_32.DLL 釋放:
int WSACleanup(
);
該函式用於釋放WS2_32.DLL,不需要Winsock功能時呼叫該函式。
2.TCP基本函式:
建立socket:
SOCKET socket (int af, int type,
int protocol);
第一個引數af: 表示族地址,網路程式設計一般使用AF_INET巨集。
第二個引數type: 表示連線型別,TCP選面向連線SOCK_STREAM,UDP選資料包SOCK_DGRAM。
第三個引數protocol: 表示協議,使用AF_INET族地址TCP連線時,設為IPPROTO_TCP。
繫結socket:
int bind(SOCKET
s, const struct sockaddr *saddr,int namelen);
第一個引數: 需要繫結的socket。
第二個引數: 對應AF_INET,使用struct sockaddr_in包含協議,IP,埠等資訊。
第三個引數: 對應AF_INET,使用struct sockaddr_in結構大小。
該函式將socket與協議,IP,埠號繫結起來,相對於給socket“命名”唯一的標識,這樣其他的程式就可以通過這個標識找到這個socket。
監聽socket:
int listen(SOCKET
s, int nQueueSize);
第一個引數: 監聽的socket。
第二個引數: 套接字監聽佇列最大連線請求數。
該函式將監聽對socket的連線請求。
請求連線:
int connect(SOCKET
s,const struct sockaddr *saddr,int namelen) ;
第一個引數: socket本地程式的socket。
第二個引數: 對應AF_INET,對方IP,埠等socket地址標識sockaddr_in。
第三個引數: 對應AF_INET,使用sockaddr_in結構大小。
接受連線請求:
SOCKET accept(SOCKET
s, struct sockaddr *addr, int *addrlen);
第一個引數: socket為被監聽的socket。
第二個引數: 對應AF_INET,一個sockaddr指標,將寫入傳送請求方的sockaddr_in資訊。
第三個引數: 對應AF_INET,sockaddr_in結構體的大小。
該函式用於接受一個socket連線請求,返回一個新的連線socket(實質是請求方的socket),傳送與接收資料通過這個連線套socket。
傳送資料:
int send(SOCKET
s, const char *buf, int len, int flags );
第一個引數: socket為對方的socket。
第二個引數: 傳送資料的緩衝區。
第三個引數: 資料緩衝區大小。
第四個引數: 緊急狀態,一般這為0。
該函式用於向對方socket傳送資料,成功返回傳送資料的大小數。
傳送資料:
int recv(SOCKET
s, char *buf, int len, int flags);
第一個引數: socket為對方的socket。
第二個引數: 接收資料的緩衝區。
第三個引數: 緩衝區大小。
第四個引數: 緊急狀態,一般這為0。
該函式用於接收對方傳送的資料,成功返回傳送資料的大小數。
關閉套接字:
int closesocket(SOCKET
s);
引數為socket。
該函式用於關閉套接字。
3.牛刀小試:
VC6.0中,先執行TCP伺服器程式,再開啟一個VC6.0,執行TCP客戶端程式。
執行效果:
伺服器端程式:
#include
#include
#pragma comment(lib,"ws2_32.lib")
int main()
{
SOCKET serversoc;
SOCKET clientsoc;
SOCKADDR_IN serveraddr;
SOCKADDR_IN clientaddr;
char buf[1024];
int len;
WSADATA wsa;
WSAStartup(MAKEWORD(2,0),&wsa); //初始化WS2_32.DLL
//建立套接字
if((serversoc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0)
{
printf("套接字socket建立失敗!\n");
return -1;
}
//命名協議,IP,埠
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9102);
serveraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
//繫結套接字
if(bind(serversoc, (SOCKADDR *)&serveraddr, sizeof(serveraddr)) != 0)
{
printf("套接字繫結失敗!\n");
return -1;
}
printf("開始監聽...\n");
//監聽請求
if(listen(serversoc, 1) != 0)
{
printf("監聽失敗!\n");
return -1;
}
len = sizeof(SOCKADDR_IN);
//接收請求
if((clientsoc = accept(serversoc, (SOCKADDR *)&clientaddr, &len))<=0)
{
printf("接受連線失敗!\n");
return -1;
}
printf("連線成功\n");
//接收資料
while(1)
{
if(recv(clientsoc, buf, 1024, 0) <= 0)
{
printf("關閉連線!\n");
closesocket(clientsoc);
}
printf("接收來自客戶端的資訊: %s\n",buf);
break;
}
//傳送資料
printf("請輸入傳送給客戶端的字元:\n");
scanf("%s", buf);
//send to client
if(send(clientsoc, buf, strlen(buf)+1, 0)<=0)
{
printf("傳送錯誤!\n");
}
WSACleanup(); //釋放WS2_32.DLL
return 0;
}
客戶端程式:
#include
#include
#pragma comment(lib,"ws2_32.lib")
int main()
{
SOCKET clientsocket;
SOCKADDR_IN serveraddr;
SOCKADDR_IN clientaddr;
char buf[1024];
WSADATA wsa;
WSAStartup(MAKEWORD(2,0),&wsa); //初始化WS2_32.DLL
//建立套接字
if((clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0)
{
printf("套接字socket建立失敗!\n");
return -1;
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9102);
serveraddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
//請求連線
printf("嘗試連線中...\n");
if(connect(clientsocket, (SOCKADDR *)&serveraddr, sizeof(serveraddr)) != 0)
{
printf("連線失敗!\n");
return -1;
}
printf("連線成功!\n");
//傳送資料
printf("請輸入傳送給伺服器的字元:\n");
scanf("%s", buf);
if(send(clientsocket, buf, strlen(buf)+1, 0)<=0)
{
printf("傳送錯誤!\n");
}
//接收資料
while(1){
if(recv(clientsocket, buf, 1024, 0) <= 0)
{
printf("關閉連線!\n");
closesocket(clientsocket);
}
printf("接收來自伺服器的資訊: %s\n",buf);
break;
}
//關閉套接字
closesocket(clientsocket);
WSACleanup(); //釋放WS2_32.DLL
return 0;
}
相關文章
- 【windows socket+UDP伺服器客戶端】WindowsUDP伺服器客戶端
- 【windows socket+HTTP伺服器客戶端】WindowsHTTP伺服器客戶端
- VNC客戶端是Windows,VNC客戶端是Windows如何進行操作VNC客戶端Windows
- vnc windows客戶端,vnc windows客戶端下載,具體使用教程。VNCWindows客戶端
- VNC客戶端推薦,Windows系統下VNC客戶端推薦VNC客戶端Windows
- Windows下安裝redis客戶端WindowsRedis客戶端
- 小弟求救伺服器-客戶端程式伺服器客戶端
- windows 上rsync客戶端使用方法Windows客戶端
- GitHub Windows客戶端無法登入GithubWindows客戶端
- 客戶端(windows)訪問FTP伺服器遇到的問題(總結)客戶端WindowsFTP伺服器
- Windows客戶端的JProfiler遠端監控Linux上的Tomcat伺服器Windows客戶端LinuxTomcat伺服器
- MQTT伺服器搭建服務端和客戶端MQQT伺服器服務端客戶端
- oracle 客戶端與伺服器端的關係Oracle客戶端伺服器
- js 客戶端與伺服器端的通訊JS客戶端伺服器
- 客戶端 post ,get 訪問伺服器客戶端伺服器
- Redis從客戶端登入伺服器Redis客戶端伺服器
- Oracle客戶端連線伺服器教程Oracle客戶端伺服器
- windows tftp客戶端,5步掌握win7開啟tftp客戶端的方法教程WindowsFTP客戶端Win7
- windows7下安裝oracle客戶端WindowsOracle客戶端
- 客戶端到伺服器端的通訊過程客戶端伺服器
- Redis原始碼剖析——客戶端和伺服器Redis原始碼客戶端伺服器
- 伺服器獲取真實客戶端 IP伺服器客戶端
- 使用 WebSocket 客戶端連線 MQTT 伺服器Web客戶端MQQT伺服器
- 客戶端怎麼連線到伺服器?客戶端伺服器
- redis伺服器/客戶端安裝與配置Redis伺服器客戶端
- 【轉載】MySQL客戶端伺服器協議MySql客戶端伺服器協議
- 客戶端Ping伺服器工具[Python]客戶端伺服器Python
- Easyvision中的伺服器與客戶端伺服器客戶端
- Thrift安裝與伺服器、客戶端的編寫執行演示(windows版本)伺服器客戶端Windows
- IT 團隊文件工具 showdoc 推出 Windows 版客戶端Windows客戶端
- 實戰:Windows防火牆保護客戶端安全Windows防火牆客戶端
- WINDOWS8.1安裝ORACLE客戶端及配置WindowsOracle客戶端
- Nagios 監控windows客戶端安裝教程iOSWindows客戶端
- windows bilibili客戶端快取影片匯出Windows客戶端快取
- dubbo客戶端客戶端
- Pulsar客戶端客戶端
- mqtt 客戶端MQQT客戶端
- windows tftp客戶端,教你幾個步驟掌握win7開啟tftp客戶端的方法WindowsFTP客戶端Win7