From <TCP IP网络编程>
socket通信的整个过程可以比喻是电话机通信
server:
#include<WinSock2.h>
int main(int argc, char* argv[])
{
WSADATA wsaData;
SOCKET hServSock,hClntSock;
SOCKADDR_IN servAddr,clntAddr;
int szClntAddr;
char message[] = "Hello World!";
if(argc != 2)
{
cout<<"Usage:"<<argv[0]<<"<port> \n"<<endl;
}
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
cout<<"wsaStartup error!"<<endl;
}
hServSock = socket(PF_INET,SOCK_STREAM,0); // 创建电话机,有了电话机才能安装电话
/**********************************************************************************************
成功返回文件描述符(linux一切皆文件,文件描述符可以看做文件的数字代号)
失败返回-1
************************************************************************************************/
if(hServSock == INVALID_SOCKET)
{
cout <<"socket() error!"<<endl;
}
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(atoi(argv[2]));
servAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
if(bind(hServSock,(SOCKADDR*) & servAddr,sizeof(servAddr)) == SOCKET_ERROR)
{
cout <<"bind error"<<endl;
}
if(listen(hServSock,5) == SOCKET_ERROR)
{
cout << "listen() error"<<endl;
}
szClntAddr = sizeof(clntAddr);
hClntSock = accept(hServSock,(SOCKADDR*) &clntAddr,&szClntAddr);
if(hClntSock == INVALID_SOCKET)
{
cout << "accept error"<<endl;
}
send(hClntSock,message,sizeof(message),0);
closesocket(hClntSock);
closesocket(hServSock);
return 0;
}
client:
#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>
using namespace std;
int main(int argc ,char* argv[])
{
WSADATA wsaData;
SOCKET hSocket;
SOCKADDR_IN servAddr;
char message[30]= "";
int strLen;
if(WSAStartup(MAKEWORD(2,2),&wsaData) !=0)
{
cout<<"WSAStartup error"<<endl;
}
hSocket = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(hSocket == INVALID_SOCKET)
{
cout <<"socket() error"<<endl;
}
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr(argv[2]);
servAddr.sin_port = htons(atoi(argv[3]));
if(connect(hSocket,(SOCKADDR*)&servAddr,sizeof(servAddr)) == SOCKET_ERROR)
{
cout<<"connect error"<<endl;
}
strLen = recv(hSocket,message,sizeof(message)-1,0);
if(strLen == -1)
{
cout << "read() error"<<endl;
}
printf("message from server : %s \n",message);
closesocket(hSocket);
WSACleanup();
system("pause");
return 0;
}
与一般的小程序不同,window socket相关的库并没有默认链接,需要手动链接该静态库
若没有链接该库,socket相关的函数实现都是无法找到而报错的,链接好之后,#include<winsock2.h>包含接口头文件直接使用即可。
当然cpp中还要另一种链接该库的方式,#pragma comment(lib,"ws2_32.lib"),通过c语言的预编译指令告诉程序需要链接该库。
上面用到了main参数,使用时在这设置
这样设置main函数的参数第一个默认为可执行文件的地址,我们使用时从argv[1]开始使用