跨平台(Windows+Linux)的Socket通讯程序(一)—底层封装

本文探讨了Windows和Linux平台下Socket通讯的区别,提供了C++编写的跨平台Socket通讯库。介绍了TCP和UDP协议特性,以及socket在不同操作系统下的使用差异,包括send和recv函数的行为分析。此外,还讨论了如何处理网络状态和UDP通讯中的数据包大小问题。
摘要由CSDN通过智能技术生成

【摘要】编写Socket通讯程序是一个老话题。本文重点介绍Windows平台和Linux平台Socket通讯的不同,采用C++,编制了一个简单的跨平台的Socket通讯库。

一、Socket通讯的基础知识

Socket通讯是两个计算机之间最基本的通讯方法,有TCP和UDP两种协议。关于这两种协议的区别,不少文章已有详述,这里,稍微总结一下:

1.TCP是面向连接的,是“流”式的,意即通讯两端建立了一个“数码流管”,该流无头无尾,接收端保证接收顺序,但不保证包的分割。

2.UDP是面向无连接的,是“包”式的,意即通讯两端自由发送数据包,接收端不保证接收顺序,但保证包的分割与发送端一致。

正是基于上述二者的不同,在编程上,它们的区别如下:对TCP连接,服务器端过程(bind->listen->accept->send/receive)与客户端不相同(connect->send/receive),对UDP连接,二者似乎更对等一些(服务器端仅需要bind)。

 

二、socket在windows下和linux下的区别

一些文章也已涉及,这里,也是综合一下,并加上自己的理解。

 

项目 Windows Linux
主要头文件 winsock.h/winsock2.h sys/socket.h fcntl.h  errno.h
链接库 ws2_32.dll/lib 连接是使用参数:-lstdc
运行时需要libstdc++.so.5,可在/usr/lib目录中创建一个链接。
初始化及退出 初始化需要调用WSAStartup,退出需调用WSACleanup
关闭Socket closesocket 与文件操作相同close
Socket类型 SOCKET 与文件句柄相同int
错误查看 WSAGetLastError 全局变量errno
设置非阻塞模式 int i=1
ioctlsocket(sockethandle,FIONBIO,&i)   
fcntl(ockethandle,F_SETFL, O_NONBLOCK)
send/recv函数最后一个参数 一般设置为0 可以有多种组合:MSG_NOSIGNAL,MSG_DONTWAIT,MSG_WAITALL
send的异常   当连接断开,还发数据的时候,不仅send()的返回值会有反映,而且还会像系统发送一个异常消息,如果不作处理,程序会退 出。为此,send()函数的最后一个参数可以设置MSG_NOSIGNAL,禁止send()函数向系统发送异常消息。
WSA宏 除了可以使用标准的socket函数外,微软自己有许多以WSA开始的函数,作为对标准socket函数的封装(可能微软感觉这些函数更好用一些吧)  

 

 

 

三、跨平台的Socket辅助程序

以下给出源代码。

sock_wrap.h代码如下,其中用到了platform.h,定义_WIN32_PLATFROM_和_LINUX_PLATFROM_两个宏。

 

#ifndef _SOCK_WRAP_H_
#define _SOCK_WRAP_H_

#include "platform.h"

#if defined(_WIN32_PLATFROM_)
#include <winsock2.h>
typedef SOCKET HSocket;
#endif

#if defined(_LINUX_PLATFORM_)
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>

typedef int HSocket;
#define SOCKET_ERROR  (-1)
#define INVALID_SOCKET  0
#endif


typedef struct
{
    int block;
    int sendbuffersize;
    int recvbuffersize;
    int lingertimeout;
    int recvtimeout;
    int sendtimeout;
} socketoption_t;

typedef struct
{
   int nbytes;
   int nresult;
} transresult_t;

int InitializeSocketEnvironment();
void FreeSocketEnvironment();
void GetAddressFrom(sockaddr_in *addr, const char *ip, int port);
void GetIpAddress(char *ip, sockaddr_in *addr);
bool IsValidSocketHandle(HSocket handle);
int GetLastSocketError();

HSocket SocketOpen(int tcpudp);
void SocketClose(HSocket &handle);

int SocketBlock(HSocket hs, bool bblock);
int SocketTimeOut(HSocket hs, int recvtimeout, int sendtimeout, int lingertimeout);

int SocketBind(HSocket hs, sockaddr_in *addr);
HSocket SocketAccept(HSocket hs, sockaddr_in *addr);
int SocketConnect(HSocket hs, struct sockaddr_in *paddr);
int SocketListen(HSocket hs, int maxconn);

void SocketSend(HSocket hs, const char *ptr, int nbytes, transresult_t &rt);
void SocketRecv(HSocket hs, char *ptr, int nbytes, transresult_t &rt);
void SocketTryRecv(HSocket hs, char *ptr, int nbytes, int milliseconds, transresult_t &rt);
void SocketTrySend(HSocket hs, const char *ptr, int nbytes, int milliseconds, transresult_t &rt);

void SocketClearRecvBuffer(HSocket hs)
跨平台socket C封装类是一种能够在不同操作系统平台上使用的通信库,用于简化网络编程过程中的底层socket操作。它提供了一系列的函数和类,使得开发者可以更方便地创建、连接、读写和关闭socket连接。 跨平台socket C封装类的设计目标是保持平台无关性,即无论在何种操作系统上编译和运行,都能够统一调用相同的接口,实现相同的功能。它兼容各种主流的操作系统,如WindowsLinux和MacOS,可以在这些平台下编写通用的网络应用程序。 在使用跨平台socket C封装类时,开发者只需要通过简单的API调用,即可完成各种socket操作,无需关心不同操作系统的细节。例如,创建一个socket连接只需调用一两个函数,并指定连接所需的IP地址和端口号即可。而读写数据只需使用简单的函数即可完成。 通过跨平台socket C封装类,开发者可以实现跨平台的网络应用程序,可以编写各种类型的客户端和服务器程序,实现网络通信、文件传输、实时消息推送等功能。无论是开发网页、移动应用还是桌面程序,只需在不同平台使用相同的封装类接口,即可实现统一的网络通信功能。 综上所述,跨平台socket C封装类是一种能够在不同操作系统平台上使用的通信库,可以大大简化网络编程中的底层socket操作,提供统一的接口,使开发者能够更方便地实现网络应用程序
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值