1. 程式人生 > >windows socket程式設計實現兩臺電腦間的通訊

windows socket程式設計實現兩臺電腦間的通訊

首先需要兩臺電腦,可以兩個同學共同來完成;當然,如果自己有兩臺電腦的話就更好了!

在一臺電腦上建立一個TCP Socket伺服器應用程式

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <WinSock2.h>
#include <stdlib.h>


#pragma comment (lib,"WS2_32.lib");
#define BUF_SIZE 64


int main()
{
WSADATA wsd;         //WSADATA變數,用於初始化Windows Socket 
SOCKET sServer;     //伺服器socket,用於監聽客戶端請求
SOCKET sClient;     //客戶端socket,用於實現與客戶端的通訊
int retVal;         //呼叫各種socket函式的返回值
char buf[BUF_SIZE];


//初始化Socket環境
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
//printf("WASStartup failed !\n");
std::cout << "WASStartup failed !" << std::endl;
return 1;
}


//建立用於監聽的Socket
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sServer == INVALID_SOCKET)
{
//printf("socket failed !\n");
std::cout << "socket failed !" << std::endl;
return -1;
}


//設定伺服器Socket地址
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(9990);
addrServ.sin_addr.S_un.S_addr = htons(INADDR_ANY);


//繫結Sockets Server 到本地地址
retVal = bind(sServer, (const struct sockaddr *)&addrServ, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == retVal)
{
std::cout << "bind failed !" << std::endl;
closesocket(sServer);
WSACleanup();
return -1;
}


//在Socket Server上進行監聽
retVal = listen(sServer,1);
if (SOCKET_ERROR==retVal)
{
std::cout << "listen failed !" << std::endl;
closesocket(sServer);
WSACleanup();
return -1;
}




//接受來自客戶端的請求
std::cout << "TCP Server Start..." << std::endl;
sockaddr_in addrClient;    //客戶端地址
int addrClientLen = sizeof(addrClient);
sClient = accept(sServer, (sockaddr FAR *)&addrClient, &addrClientLen);
if (INVALID_SOCKET == sClient)
{
std::cout << "accept failed !" << std::endl;
closesocket(sServer);
WSACleanup();
return -1;
}




//在伺服器與客戶端之間傳送和接收資料


//迴圈接受客戶端的資料,直接客戶端傳送quit命令後退出
while (true)
{
memset(buf, 0, BUF_SIZE);
retVal = recv(sClient, buf, BUF_SIZE, 0);
if (SOCKET_ERROR == retVal)
{
std::cout << "recv failed !" << std::endl;
closesocket(sServer);
WSACleanup();
return -1;
}
//獲取當前系統時間
SYSTEMTIME st;
GetLocalTime(&st);
char sDataTime[30];
sprintf(sDataTime, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
//列印輸出資訊
std::cout << sDataTime << "Recv from Client [" << inet_ntoa(addrClient.sin_addr) << ":";
std::cout << addrClient.sin_port << "] : " << buf << std::endl;


//如果客戶端傳送“quit”字串,則伺服器退出
if (strcmp(buf, "quit") == 0)
{
retVal = send(sClient, "quit", strlen("quit"), 0);
break;
}
//否則向客戶端傳送回顯字串
else
{
char msg[BUF_SIZE];
sprintf(msg, "Message received - %s", buf);
retVal = send(sClient, msg, strlen(msg), 0);
if (SOCKET_ERROR == retVal)
{
std::cout << "send failed !" << std::endl;
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
}


}


//釋放資源
closesocket(sServer);
closesocket(sClient);
WSACleanup();




system("pause");
return 0;


}

接著在另一臺電腦上建立一個TCP Socket客戶端應用程式

#include <iostream>
#include <stdio.h>
#include <WinSock2.h>
#include <string>
#include <stdlib.h>


#pragma comment (lib,"ws2_32.lib")
#define BUF_SIZE  64


int main()
{
WSADATA wsd;   //用於初始化Windows socket
SOCKET sHost;   //與伺服器進行通訊的socket
SOCKADDR_IN servAddr;  //伺服器地址
char buf[BUF_SIZE];   //用於接收資料緩衝區
int retVal;    //呼叫各種Socket函式的返回值


//初始化socket動態庫
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
std::cout<<"WSAStartup failed !"<<std::endl;
return -1;
}


//建立用於通訊的socket
sHost=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET==sHost)
{
std::cout<<"socket failed !"<<std::endl;
WSACleanup();;
return -1;
}




//設定伺服器Socket地址
servAddr.sin_family=AF_INET;
//使用者需要根據實際情況修改
servAddr.sin_addr.S_un.S_addr=inet_addr("192.168.88.103");   
servAddr.sin_port=htons(9990);
int sServerAddrlen=sizeof(servAddr);




//連線到伺服器
retVal=connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr));   
if(SOCKET_ERROR==retVal)
{
std::cout<<"connect failed !"<<std::endl;
closesocket(sHost);
WSACleanup();
return -1;
}


//在客戶端與伺服器之間傳送和接收資料
while(true)
{
std::cout<<"Please input a string to send: ";
std::string str;
 //接收輸入的資料
std::getline(std::cin,str);
 //將使用者輸入的資料複製到buf鍾
ZeroMemory(buf,BUF_SIZE);
strcpy(buf,str.c_str());


//向伺服器傳送資料
retVal=send(sHost,buf,strlen(buf),0);
if(SOCKET_ERROR==retVal)
{
std::cout<<"send failed !"<<std::endl;
closesocket(sHost);
WSACleanup();
return -1;
}


//接收伺服器回傳的資料
retVal=recv(sHost,buf,sizeof(buf)+1,0);
std::cout<<"Recv from Server: "<<buf<<std::endl;


if(strcmp(buf,"quit")==0)
{
std::cout<<"quit!"<<std::endl;
break;
}
}


//釋放資源
closesocket(sHost);
WSACleanup();


system("pause");


return 0;
}

如果在獲取伺服器ip地址時出現問題的話,別慌,一般情況下,開啟360安全衛士,開啟流量防火牆,點選區域網防護,檢視詳情就可以看到本機ip地址