跨平台网络通讯要注意的地方

跨平台网络通讯要注意的地方:(以bsd unix与winsock2为例)

1.套接口数据类型和错误数值
为了保持与 BSD 的兼容性,应用程序可以加入以下一行代码:
#define INVALID_SOCKET -1
例如:
  BDS 风格
  m_hSocket=socket(…);
  if(m_hSocket=-1)   /* or m_hSocket<0 */
                {…}
  Windows风格:
  m_hSocket=socket(…);
  if(m_hSocket=INVALID_SOCKET)
                {…}
2.select() 函数和FD_*宏
常用FD_*宏来防止错误。
3.错误代码-errno,h_errno,WSAGetLastError()
为了保持与 BSD 的兼容性,应用程序可以加入以下一行代码:
#define WSAGetLastError() errno
例如:
  BSD风格:
  retcode=recv(…);
  if(retcode=-1 && errno=EWOULDBLOCK)
  {…}
  Windows风格:
  retcode=recv(…);
  if(retcode=-1 && WSAGetLastError ()=EWOULDBLOCK)
  {…}
4.重命名的函数
#define closesocket(a) close(a)
#define ioctlsocket ioctl
5.阻塞
windows虽然支持阻塞,但常用的是非阻塞,而bsd socket默认是阻塞的。
6.头文件与库
window下只需加载头文件winsock2.h, 但在链接时要加载依赖库:ws2_32.lib; linux下网络通讯模块是包含在基本的系统库里了,只需根据调用函数包含不同的头文件即可了。
下面是一个在linux与windows下都能运行的跨平台网络程序范例:
/**//**********************************************************
* socket_test.cpp     for test socket on windows and linux
* Copyright (C) |2006-11-9| by denny <wqf363@hotmail.com>
**********************************************************/
#include <stdio.h>
#include <string.h>
#ifndef WIN32
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define closesocket(a) close(a)
#else
#include <winsock2.h>
#endif

#define MAXBUF 512
#define PORT 2222

typedef void* (*tc_thread_func)(void*);

void rcv();                /**//*后台接收消息的函数 */
void snd();                /**//*发送消息的函数*/

/**//*简介:该程序是一个跨平台的一个简单的基于UDP协议聊天工具
功能:主线程:发送消息
            子线程:接收消息
作者:wjfree
使用:运行后发送消息:IP +空格+ Message
编译:linux 下:gcc ./chatlin.c -lpthread -o chat
          win下:在lcc下添加工程,编译
*/
int main ()
{
#ifdef WIN32
        WSADATA         wsaData;
        WORD wVersionRequested = MAKEWORD( 2, 2 );
        int err = WSAStartup( wVersionRequested, &wsaData );
        HANDLE      hThread;
        DWORD       dwThreadId;
        hThread= CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)rcv,NULL,0,&dwThreadId);
        snd();
        WSACleanup();
#else
        pthread_t id;
        int ret;
        ret = pthread_create(&id,NULL,(tc_thread_func)rcv,NULL);        /**//*创建一个线程*/
        snd();
#endif
        return 0;
}

/**//*函数:snd()
功能:用scanf()函数接收ip地址和消息内容,发到对应的IP上
作者:wjfree
*/
void snd()
{

    struct     sockaddr_in name;
    int        sock;
    name.sin_family = PF_INET;
    name.sin_port = htons(PORT);
    sock = socket(PF_INET, SOCK_DGRAM,0);
    if (sock < 0)
    {
            printf("make socket error ");
            return;
    }
    while(1)
    {
        char bufloc[MAXBUF];
        char ipaddr[17];
        scanf("%s%s" , ipaddr, bufloc);
        int i = name.sin_addr.s_addr = inet_addr(ipaddr);
        if (i == -1)
        {
            printf("IP address format error! ");
        }
        else
        {
                int i = sendto(sock, bufloc, strlen(bufloc), 0, (struct sockaddr *)&name, sizeof(name));
                if (i < 0)
                        printf("Can not send the message to %s ", ipaddr);
        }
    }
   closesocket(sock);
}

/**//*函数:snd()
功能:接收消息并显示在终端
作者:wjfree
*/
void rcv()
{
    struct sockaddr_in RecvAddr;
    struct sockaddr_in SenderAddr;
    int    sock;
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    RecvAddr.sin_family = AF_INET;
    RecvAddr.sin_port = htons(PORT);
    RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    bind(sock, (struct sockaddr *) &RecvAddr, sizeof(RecvAddr));
    printf("Receiving datagrams... ");
    while(1)
    {
        int size = sizeof(SenderAddr);
        char RecvBuf[MAXBUF];
        int BufLen = MAXBUF;
        int i = recvfrom(sock,
            RecvBuf,
            BufLen,
            0,
            (struct sockaddr *)&SenderAddr,
            (size_t*)&size);
        RecvBuf[i] = 0;
        printf("%s: %s ", inet_ntoa(SenderAddr.sin_addr),RecvBuf);
    }
closesocket(sock);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值