现在的位置: 首页 > 综合 > 正文

用winsock实现进程间通信

2013年01月02日 ⁄ 综合 ⁄ 共 4356字 ⁄ 字号 评论关闭

winsock不止可以用于网络通信,也可以用于进程间的通信。比如说在一台电脑上,服务端和客户端的IP地址相等,再开通一个端口,就可以很方便的进行进程间通信了。

服务端需要做的事情是:

1socket初始化

2、绑定端口

3、监听

4、连接请求

5、通信-发送信息或者接收信息

客户端需要做是的事情:

1、初始化socket

2、请求连接端口

3、进程通信-从端口读取信息,或者向端口发送信息

我这里有一个例子,可以详细说明通信的过程和原理,在这里将要有两个进程,process1process2,其中前者可以作为服务端(其实这个不是很重要,哪个做服务端都可以,端口通信是双向的),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;

}

抱歉!评论已关闭.