大部分公司的网络通信(比如服务器)程序都是部署在linux平台上的,但很多时候也是需要支持windows平台。本文讲述移植到windows的方法。
下面是一个linux socket通讯的简单例子
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <iostream>
using namespace std;
int main()
{
//1. 创建套接字
int sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sockfd < 0)
{
cout << "TCP socket failed" << endl;
return 0;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(18989);
//此处我们使用的公网ip
addr.sin_addr.s_addr = inet_addr("118.89.67.215");
int ret = connect(sockfd,(struct sockaddr *)&addr,sizeof(addr));
if(ret < 0)
{
cout << "connnect failed" << endl;
return 0;
}
//3.接收和发送数据
while(1)
{
char buf[1024] = {0};
sprintf(buf,"10+200+11");
ssize_t send_ret = send(sockfd,buf,strlen(buf),0);
if(send_ret < 0)
{
cout << "send failed" << endl;
continue;
}
ssize_t recv_size = recv(sockfd,buf,sizeof(buf)-1,0);
if(recv_size < 0)
{
cout << "recv failed" << endl;
continue;
}
else if(recv_size == 0)
{
cout << "Peer close" << endl;
close(sockfd);
return 0;
}
cout << "recv data is : " << buf << endl;
}
close(sockfd);
return 0;
}
将其转换为windows平台下的代码如下:
//#include <unistd.h>
//#include <sys/socket.h>
#include <string.h>
//#include <arpa/inet.h>
//#include <netinet/in.h>
#include <iostream>
#include <Winsock2.h>
#include <WS2tcpip.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
typedef unsigned short uint16_t;
#endif
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return 0;
}
//1. 创建套接字
int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0)
{
cout << "TCP socket failed" << endl;
return 0;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(18989);
//此处我们使用的公网ip
addr.sin_addr.s_addr = inet_addr("118.89.67.215");
int ret = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
if (ret < 0)
{
cout << "connnect failed" << endl;
return 0;
}
//3.接收和发送数据
while (1)
{
char buf[1024] = { 0 };
sprintf(buf, "10+200+11");
ssize_t send_ret = send(sockfd, buf, strlen(buf), 0);
if (send_ret < 0)
{
cout << "send failed" << endl;
continue;
}
ssize_t recv_size = recv(sockfd, buf, sizeof(buf) - 1, 0);
if (recv_size < 0)
{
cout << "recv failed" << endl;
continue;
}
else if (recv_size == 0)
{
cout << "Peer close" << endl;
closesocket(sockfd);
return 0;
}
cout << "recv data is : " << buf << endl;
}
closesocket(sockfd);
return 0;
}
简单来讲,就是得要:
(1)注释掉linux下的头文件,添加windows下socket的头文件,比如#include <Winsock2.h>
#include <WS2tcpip.h>
(2)增加别名:
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
typedef unsigned short uint16_t;
#endif
(3)添加静态链接库:#pragma comment(lib, "ws2_32.lib")
(4)增加启动命令:
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return 0;
}
(5)将close函数替换为closesocket函数
(6)去掉SDL检查
完成上面操作后,我们发现windows下的程序可以编译运行成功了。当然socket编程在windows和linux下的区别还有很多,以上展示的只是一个最简单的例子,具体可以参考:《socket编程在windows和linux下的区别》。学习完这个后更进一步,我们可以通过宏定义等方式编写跨平台的服务器程序使其可以同时支持linux、windows。