| 定義變數——獲得WINSOCK版本——載入WINSOCK庫——初始化——建立通訊端 ——設定通訊端選項——關閉通訊端——卸載WINSOCK庫——釋放所有資源
整個程式架構分為兩大部分,伺服器端用戶端。
伺服器SOCKET程式流程
socket()→bind()→listen→accept()→recv()/send()→closesocket()
用戶端:
socket→connect()→send()/recv()→closesocket()
伺服器代碼:
#include <winsock2.h>
#pragma comment(lib,"ws2_32")
#include <stdio.h>
int main(int argc, char* argv[])
{
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2, 2);
//載入winsock庫
if(WSAStartup(sockVersion, &wsaData) != 0)
return 0;
// 建立套節字
SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sListen == INVALID_SOCKET)
{
printf("socket error/n");
return 0;
}
// 在sockaddr_in結構中裝入地址資訊
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(4500); // htons函數 將主機的無符號短整形數轉換成網路
//位元組順序
sin.sin_addr.S_un.S_addr = INADDR_ANY;
// 使通訊端和本地地址綁定
if(bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf(" bind error /n");
closesocket(sListen);
return 0;
}
// 設定通訊端進入監聽模式
if(listen(sListen, 5) == SOCKET_ERROR)
{
printf("listen error/n");
closesocket(sListen);
return 0;
}
// 迴圈接受客戶的串連請求
sockaddr_in remoteAddr;
SOCKET sClient;
int nAddrLen = sizeof(remoteAddr);
char revData[255];
while(TRUE)
{
// 接受一個新串連
sClient = accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen);
//accept函數調用失敗則繼續等待串連。
if(sClient == INVALID_SOCKET)
{
printf("accept() error");
continue;
}
//列印出串連者的ip
printf(" 接受到一個串連:%s /r/n", inet_ntoa(remoteAddr.sin_addr));
//直到收到有效資料時才列印出來
int ret=recv(sClient,revData,255,0);
if(ret>0)
{
//為了防止列印出錯,把字串結尾設成0x00
revData[ret]=0x00;
printf(revData);
}
char *buff="/r/n學習SOCKET編程/r/n";
//發送資料
send(sClient,buff,strlen(buff),0);
// 關閉通訊端控制代碼,結束會話
closesocket(sClient);
}
closesocket(sListen);
WSACleanup();
return 0;
}
用戶端代碼:
#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib,"ws2_32")
#include <stdio.h>
int main(int argc, char* argv[])
{
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2, 2);
//載入winsock庫
if(WSAStartup(sockVersion, &wsaData) != 0)
return 0;
// 建立套節字
SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sClient == INVALID_SOCKET)
{
printf("socket error/n");
return 0;
}
// 在sockaddr_in結構中裝入伺服器端地址資訊
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(4500);// htons函數 將主機的無符號短整形數轉換成網路
//位元組順序,4500連接埠為要串連伺服器端的連接埠
servAddr.sin_addr.S_un.S_addr =inet_addr("127.0.0.1");//伺服器端ip
//串連伺服器端
if(connect(sClient,(sockaddr*)&servAddr,sizeof(servAddr))==SOCKET_ERROR)
{
printf("connect error/n");
closesocket(sClient);
return 0;
}
char *buff="/r/nSOCKET編程,我來了/r/n";
//發送資料
send(sClient,buff,strlen(buff),0);
char revData[255];
//直到收到有效資料時才列印出來
int ret=recv(sClient,revData,255,0);
if(ret>0)
{
//為了防止列印出錯,把字串結尾設成0x00
revData[ret]=0x00;
printf(revData);
}
closesocket(sClient);
WSACleanup();
return 0;
} |