winsock不止可以用于网络通信,也可以用于进程间的通信。比如说在一台电脑上,服务端和客户端的IP地址相等,再开通一个端口,就可以很方便的进行进程间通信了。
服务端需要做的事情是:
1、socket初始化
2、绑定端口
3、监听
4、连接请求
5、通信-发送信息或者接收信息
客户端需要做是的事情:
1、初始化socket
2、请求连接端口
3、进程通信-从端口读取信息,或者向端口发送信息
我这里有一个例子,可以详细说明通信的过程和原理,在这里将要有两个进程,process1和process2,其中前者可以作为服务端(其实这个不是很重要,哪个做服务端都可以,端口通信是双向的),process1将向process2发送一个数字,然后process2将返回一个数字,这就是一个简单的通信过程。
process1的代码如下所示:
//process1.c
#include<winsock2.h>
#include<windows.h>
#include<stdio.h>
# define PORT 2500
#define pf printf
#define MSG_LEN 32
void clear_str(char*pc)//清空字符串
{
if(pc!=NULL)
while(*pc)*pc++='\0';
}
int uint2str(unsigned int ui,char*pc)//无符号整数转换成字符串
{
char c;
char*temp=pc;
if(pc==NULL)return 0;
clear_str(pc);
while(ui>9)
{
*temp++=ui%10+'0';
ui/=10;
}
*temp=ui+'0';
while(temp>pc)
{c=*temp;*temp=*pc;*pc=c;temp--;pc++;}
return 1;
}
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int ret=0,salength=0;
unsigned int sd;
SOCKET server,slisten;
struct sockaddr_in saserver,saclient;
char msg[MSG_LEN]="";
//WinSock初始化
wVersionRequested=MAKEWORD(2, 2); //希望使用的WinSock DLL 的版本
ret=WSAStartup(wVersionRequested, &wsaData);
if(ret!=0)return 0;
//创建Socket,使用TCP协议
server=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server== INVALID_SOCKET)
{ WSACleanup();return 0;}
pf("socket()成功!\n");
//构建本地地址信息
saserver.sin_family = AF_INET; //地址家族
saserver.sin_port = htons(PORT); //注意转化为网络字节序
saserver.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //使用INADDR_ANY 指示任意地址
//绑定
ret = bind(server,(struct sockaddr *)&saserver, sizeof(saserver));
if (ret == SOCKET_ERROR)
{closesocket(server); WSACleanup();return 0;}
pf("bind()成功!\n");
//侦听连接请求
ret = listen(server, 5);
if (ret == SOCKET_ERROR)
{closesocket(server); WSACleanup();return 0;}//关闭套接字
pf("等待连接……\n");
salength=sizeof(saclient);
//接受客户端的连接请求
slisten=accept(server,(struct sockaddr *)&saclient,&salength);
if(slisten==INVALID_SOCKET)//失败则退出
{closesocket(server); WSACleanup();return 0;}
pf("accept()成功!\n");
sd=0;
while(1)
{
scanf("%d",&sd);//输入要发送的数字
uint2str(sd,msg);
ret=send(slisten,msg,sizeof(msg),0);//发送一个数字
if(ret==SOCKET_ERROR)break;//发送失败
clear_str(msg);
ret=recv(slisten,msg,sizeof(msg),0);//接收回复
if(ret==0){pf("对方已关闭socket!\n");break;}
if(ret==SOCKET_ERROR)break;//接收失败
pf("recv message:%s\n",msg);
}
closesocket(server);//关闭套接字
closesocket(slisten);//关闭套接字
WSACleanup();
return 1;
}
process2的代码如下所示:
//process2.c
#include<winsock2.h>
#include<windows.h>
#include<stdio.h>
# define PORT 2500
#define pf printf
#define MSG_LEN 32
int getIP(char*pIP)//获取IP地址
{
char hostname[128];
struct hostent *pHost =NULL;
if(pIP!=NULL)
{
if(gethostname(hostname,sizeof(hostname))==0)
{
pHost=gethostbyname(hostname);
if(pHost!=NULL)
strcpy(pIP,inet_ntoa(*(struct in_addr *)*pHost->h_addr_list));
return 1;
}
else
return 0;
}
else
{
printf("获取IP地址失败!\n");return 0;
}
}
int str2uint(char*pc)//将字符串还原为无符号整数
{
int d=0;
if(pc==NULL)return -1;//无效字符串
while(*pc)
if(*pc<'0'||*pc>'9')return -1;
else d=10*d+*pc++-'0';
return d;
}
void clear_str(char*pc)//清空字符串
{
if(pc!=NULL)
while(*pc)*pc++='\0';
}
int uint2str(unsigned int ui,char*pc)//无符号整数转换成字符串
{
char c;
char*temp=pc;
if(pc==NULL)return 0;
clear_str(pc);
while(ui>9)
{
*temp++=ui%10+'0';
ui/=10;
}
*temp=ui+'0';
while(temp>pc)
{c=*temp;*temp=*pc;*pc=c;temp--;pc++;}
return 1;
}
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int ret=0,salength=0;
unsigned int ans;
SOCKET server;
struct sockaddr_in saserver;
char msg[MSG_LEN]="";
char IP[MSG_LEN]="";//本机IP地址
//WinSock初始化
wVersionRequested = MAKEWORD(2, 2); //希望使用的WinSock DLL的版本
ret = WSAStartup(wVersionRequested, &wsaData);
if(ret!=0)
{printf("WSAStartup() failed!\n");return 0;}
//确认WinSock DLL支持版本2.2
if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2)
{WSACleanup();pf("无效套接字!\n");return 0;}
//创建Socket,使用TCP协议
server= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server== INVALID_SOCKET)
{ WSACleanup();pf("创建套接字失败!\n");return 0;}
getIP(IP);
//构建服务器地址信息
saserver.sin_family = AF_INET; //地址家族
saserver.sin_port = htons(PORT); //注意转化为网络节序
saserver.sin_addr.S_un.S_addr = inet_addr(IP);
//连接服务器
ret = connect(server, (struct sockaddr *)&saserver, sizeof(saserver));
if (ret == SOCKET_ERROR)
{pf("连接失败!\n");
closesocket(server); WSACleanup();return 0;
}
while(1)
{
ret=recv(server,msg,sizeof(msg),0);//接收信息
if(ret==0){pf("服务端已关闭!\n");break;}//u失败
if(ret==SOCKET_ERROR)break;
pf("recv message:%s\n",msg);
ans=str2uint(msg);
if(ans<10)ans=ans*ans;
else ans=ans/10;
uint2str(ans,msg);
ret=send(server,msg,sizeof(msg),0);//发送信息
if(ret==SOCKET_ERROR)break;
clear_str(msg);//清空
}
closesocket(server);
WSACleanup();
return 0;
}