socket windows linux,socket server

大家好,感谢邀请,今天来为大家分享一下socket windows linux的问题,以及和socket server的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!

Windows Socket和Linux Socket编程的区别

SOCKET在原理上应该是一样的,只是不同系统的运行机置有些不同。

Socket编程 windows到Linux代码移植遇到的问题

1、一些常用函数的移植

2、网络

socket相关程序从windows移植到linux下需要注意的

1)头文件

windows下winsock.h/winsock2.h

linux下sys/socket.h

错误处理:errno.h

其他常用函数的头文件可到命令行下用man指令查询。

2)初始化

windows下需要用WSAStartup

linux下不需要(很方便),直接可以使用

3)关闭socket

windows下closesocket(...)

linux下close(...)

4)类型

windows下SOCKET

在linux下为int类型

5)绑定地址的结构体

名称相同,都是struct sockaddr、struct sockaddr_in,这两者通常转换使用;

在Windows下面名称都是大写,而在Linux下为小写

常用:

Linux下:

sockaddr_in destAddr;

destAdd.sin_family=AF_INET;

destAddr.sin_port=htons(2030);

destAddr.sin_addr.s_addr=inet_addr("192.168.1.1");

Windows下:

SOCKADDR_IN destAddr;

destAddr.sin_addr.S_un.S_addr=inet_addr("192.168.1.1");

但结构体中成员的名称不同

Windows中结构体成员

struct sockaddr_in{

short sin_family;

u_short sin_port;

struct in_addr sin_addr;

char sin_zero[8];

};

struct sockaddr{

u_short sa_family;

char sa_data[14];

};

struct in_addr{

union{

struct{ u_char s_b1,s_b2,s_b3,s_b4;} S_un_b;

struct{ u_short s_w1,s_w2;} S_un_w;

u_long S_addr;

} S_un;

};

下面的一些宏可以使windows下的程序移植到linux下(通过类型的重新定义,使代码具有linux和windows下的移植性)

[cpp] view plaincopy

#ifdef WIN32

typedef int socklen_t;

typedef int ssize_t;

#endif

#ifdef __LINUX__

typedef int SOCKET;

typedef unsigned char BYTE;

typedef unsigned long DWORD;

#define FALSE 0

#define SOCKET_ERROR(-1)

#endif

[cpp] view plaincopy

#ifdef WIN32

typedef int socklen_t;

typedef int ssize_t;

#endif

#ifdef __LINUX__

typedef int SOCKET;

typedef unsigned char BYTE;

typedef unsigned long DWORD;

#define FALSE 0

#define SOCKET_ERROR(-1)

#endif

6)获取错误码

windows下getlasterror()/WSAGetLastError()

linux下errno变量

7)设置非阻塞

windows下ioctlsocket()

linux下fcntl()<fcntl.h>

8)send函数最后一个参数

windows下一般设置为0

linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可能会导致程序退出。

9)毫秒级时间获取

windows下GetTickCount()

linux下gettimeofday()

10)数据类型的一些转化

通用的:

小端到大端(网络协议使用)的转换:htonl, htons

点分十进制IP和整数之间的相互转换:inet_addr()(该函数将点分十进制转为整数),inet_aton(),inet_ntoa(),inet_pton()(linux下独有该函数可以实现相互之间的转换)

使用到的头文件不相同,linux下用man命令查询。

另外注意:

linux下使用的套接字为伯克利套接字,因此在select()函数的使用上(第一个参数的设置)也有区别;

windows下为了与伯克利套接字匹配,第一个参数是无所谓,一般可设为0;

int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!

3、多线程

多线程:(win)process.h--〉(linux)pthread.h

_beginthread--> pthread_create

_endthread--> pthread_exit

socket编程在windows和linux下的区别

下面大概分几个方面进行罗列:

Linux要包含

[cpp]

#include<sys/socket.h>

#include<netinet/in.h>

#include<netdb.h>

#include<arpa/inet.h>

等头文件,而windows下则是包含

[cpp]

#include<winsock.h>

Linux中socket为整形,Windows中为一个SOCKET。

Linux中关闭socket为close,Windows中为closesocket。

Linux中有变量socklen_t,Windows中直接为int。

因为linux中的socket与普通的fd一样,所以可以在TCP的socket中,发送与接收数据时,直接使用read和write。而windows只能使用recv和send。

设置socet选项,比如设置socket为非阻塞的。Linux下为

[cpp]

flag= fcntl(fd, F_GETFL);

fcntl(fd, F_SETFL, flag| O_NONBLOCK);

,Windows下为

[cpp]

flag= 1;

ioctlsocket(fd, FIONBIO,(unsigned long*)&flag);

当非阻塞socket的TCP连接正在进行时,Linux的错误号为EINPROGRESS,Windows的错误号为WSAEWOULDBLOCK。

file

Linux下面,文件换行是"\n",而windows下面是"\r\n"。

Linux下面,目录分隔符是"/",而windows下面是"\"。

Linux与Windows下面,均可以使用stat调用来查询文件信息。但是,Linux只支持2G大小,而Windows只支持4G大小。为了支持更大的文件查询,可以在Linux环境下加

_FILE_OFFSET_BITS=64定义,在Windows下面使用_stat64调用,入参为struct __stat64。

Linux中可根据stat的st_mode判断文件类型,有S_ISREG、S_ISDIR等宏。Windows中没有,需要自己定义相应的宏,如

[cpp]

#define S_ISREG(m)(((m)& 0170000)==(0100000))

#define S_ISDIR(m)(((m)& 0170000)==(0040000))

Linux中删除文件是unlink,Windows中为DeleteFile。

time

Linux中,time_t结构是长整形。而windows中,time_t结构是64位的整形。如果要在windows始time_t为32位无符号整形,可以加宏定义,_USE_32BIT_TIME_T。

Linux中,sleep的单位为秒。Windows中,Sleep的单位为毫秒。即,Linux下sleep(1),在Windows环境下则需要Sleep(1000)。

Windows中的timecmp宏,不支持大于等于或者小于等于。

Windows中没有struct timeval结构的加减宏可以使用,需要手动定义:

[cpp]

#define MICROSECONDS(1000* 1000)

#define timeradd(t1, t2, t3) do{\

(t3)->tv_sec=(t1)->tv_sec+(t2)->tv_sec;\

(t3)->tv_usec=(t1)->tv_usec+(t2)->tv_usec% MICROSECONDS;\

if((t1)->tv_usec+(t2)->tv_usec> MICROSECONDS)(t3)->tv_sec++;\

} while(0)

#define timersub(t1, t2, t3) do{\

(t3)->tv_sec=(t1)->tv_sec-(t2)->tv_sec;\

(t3)->tv_usec=(t1)->tv_usec-(t2)->tv_usec;\

if((t1)->tv_usec-(t2)->tv_usec< 0)(t3)->tv_usec--,(t3)->tv_usec+= MICROSECONDS;\

} while(0)

调用进程

Linux下可以直接使用system来调用外部程序。Windows最好使用WinExec,因为WinExec可以支持是打开还是隐藏程序窗口。用WinExec的第二个入参指明,如

SW_SHOW/SW_HIDE。

杂项

Linux为srandom和random函数,Windows为srand和rand函数。

Linux为snprintf,Windows为_snprintf。

同理,Linux中的strcasecmp,Windows为_stricmp。

错误处理

Linux下面,通常使用全局变量errno来表示函数执行的错误号。Windows下要使用GetLastError()调用来取得。

Linux环境下仅有的

这些函数或者宏,Windows中完全没有,需要用户手动实现。

atoll

[cpp]

long long

atoll(const char*p)

{

int minus= 0;

long long value= 0;

if(*p=='-')

{

minus++;

p++;

}

while(*p>='0'&&*p<='9')

{

value*= 10;

value+=*p-'0';

p++;

}

return minus? 0- value: value;

}

gettimeofday

[cpp]

#if defined(_MSC_VER)|| defined(_MSC_EXTENSIONS)

#define EPOCHFILETIME 11644473600000000Ui64

#else

#define EPOCHFILETIME 11644473600000000ULL

#endif

struct timezone

{

int tz_minuteswest;

int tz_dsttime;

};

int

gettimeofday(struct timeval*tv, struct timezone*tz)

{

FILETIME ft;

LARGE_INTEGER li;

__int64 t;

static int tzflag;

if(tv)

{

GetSystemTimeAsFileTime(&ft);

li.LowPart= ft.dwLowDateTime;

li.HighPart= ft.dwHighDateTime;

t= li.QuadPart;/* In 100-nanosecond intervals*/

t-= EPOCHFILETIME;/* Offset to the Epoch time*/

t/= 10;/* In microseconds*/

tv->tv_sec=(long)(t/ 1000000);

tv->tv_usec=(long)(t% 1000000);

}

if(tz)

{

if(!tzflag)

{

_tzset();

tzflag++;

}

tz->tz_minuteswest= _timezone/ 60;

tz->tz_dsttime= _daylight;

}

return 0;

}

编译相关

当前函数,Linux用__FUNCTION__表示,Windows用__func__表示。

--------------------------------------------------------------------------------

Socket编程 windows到Linux代码移植遇到的问题

1)头文件

windows下winsock.h/winsock2.h

linux下sys/socket.h

错误处理:errno.h

2)初始化

windows下需要用WSAStartup

linux下不需要

3)关闭socket

windows下closesocket(...)

linux下close(...)

4)类型

windows下SOCKET

linux下int

如我用到的一些宏:

#ifdef WIN32

typedef int socklen_t;

typedef int ssize_t;

#endif

#ifdef __LINUX__

typedef int SOCKET;

typedef unsigned char BYTE;

typedef unsigned long DWORD;

#define FALSE 0

#define SOCKET_ERROR(-1)

#endif

5)获取错误码

windows下getlasterror()/WSAGetLastError()

linux下errno变量

6)设置非阻塞

windows下ioctlsocket()

linux下fcntl()<fcntl.h>

7)send函数最后一个参数

windows下一般设置为0

linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可能会导致程序退出。

8)毫秒级时间获取

windows下GetTickCount()

linux下gettimeofday()

3、多线程

多线程:(win)process.h--〉(linux)pthread.h

_beginthread--> pthread_create

_endthread--> pthread_exit

-----------------------------------------------------------------

windows与linux平台使用的socket均继承自Berkeley socket(rfc3493),他们都支持select I/O模型,均支持使用getaddrinfo与getnameinfo实现协议无关编程。但存在细微差别,

主要有:

头文件及类库。windows使用winsock2.h(需要在windows.h前包含),并要链接库ws2_32.lib;linux使用netinet/in.h, netdb.h等。

windows下在使用socket之前与之后要分别使用WSAStartup与WSAClean。

关闭socket,windows使用closesocket,linux使用close。

send*与recv*函数参数之socket长度的类型,windows为int,linux为socklen_t,可预编译指令中处理这一差异,当平台为windows时#define socklen_t unsigned int。

select函数第一个参数,windows忽略该参数,linux下该参数表示集合中socket的上限值,一般设为sockfd(需select的socket)+ 1。

windows下socket函数返回值类型为SOCKET(unsigned int),其中发生错误时返回INVALID_SOCKET(0),linux下socket函数返回值类型int,发生错误时返回-1。

另外,如果绑定本机回环地址,windows下sendto函数可以通过,linux下sendto回报错:errno=22, Invalid arguement。一般情况下均绑定通配地址。

转载jlins

socket在windows下和linux下的区别

1)头文件

windows下winsock.h/winsock2.h

linux下sys/socket.h错误处理:errno.h

2)初始化

windows下需要用WSAStartup

WSADATA wsaData;

err= WSAStartup(0x202,&wsaData);

if( err!= 0)

{

return 0;

}

else if( LOBYTE( wsaData.wVersion)!= 2|| HIBYTE( wsaData.wVersion)!= 2)//检测是否支持这个版本的socket

{

WSACleanup();

return 0;

}

对应的退出清理用WSACleanup();

linux下不需要

3)关闭socket

windows下closesocket(...)

linux下close(...)

4)socket类型

windows下SOCKET

linux下int

5)获取错误码

windows下WSAGetLastError()

linux下errno变量

extern int errno;

int geterror(){return errno;}

6)设置非阻塞

windows下ioctlsocket(server_socket,FIONBIO,&ul); int ul= 1

linux下fcntl(server_socket,F_SETFL, O_NONBLOCK);<fcntl.h>

7)send函数最后一个参数

windows下一般设置为0

linux下必须是后几个参数用到的socket中,值最大的数(整型)加1(另一种说法是设置为MSG_NOSIGNAL)

8)毫秒级时间获取

windows下GetTickCount()

linux下gettimeofday()

9)编译连接

windows下ws2_32.lib

linux下

连接是使用参数:-lstdc

运行时需要libstdc++.so.5,可在/usr/lib目录中创建一个链接。

10)Socket操作错误返回值

都为SOCKET_ERROR,他的值是-1

11)异常处理

windows下没有对send()的异常处理,最后一个参数无效,写0就可以了。

linux下

当连接断开,还发数据的时候,不仅send()的返回值会有反映,而且还会像系统发送一个异常消息,如果不作处理,系统会出BrokePipe,程序会退出。为此,send()函数的最后一个参数可以设置MSG_NOSIGNAL,禁止send()函数向系统发送异常消息。

12)WSA宏

windows下WSA相关的操作

linux下WSA相关的操作在Linux不必要,直接去掉即可

3、多线程

多线程:(win)process.h--〉(linux)pthread.h

_beginthread--> pthread_create

_endthread--> pthread_exit

阅读剩余
THE END