当前位置:首页 » 操作系统 » socket返回值linux

socket返回值linux

发布时间: 2022-10-17 04:52:39

linux下 socket函数的返回值代表什么

int socket;domain指明所使用的协议族,通常为PF_INET,表示互联网协议族;type参数指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket,允许程序使用低层协议;protocol通常赋值"0"。

Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。 Socket描述符是一个指向内部数据结构的指针,它指向描述符表入口。

调用Socket函数时,socket执行体将建立一个Socket,实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。 Socket执行体为你管理描述符表。

(1)socket返回值linux扩展阅读:

支持下述类型描述:

SOCK_STREAM 提供有序的、可靠的、双向的和基于连接的字节流,使用带外数据传送机制,为Internet地址族使用TCP。

SOCK_DGRAM 支持无连接的、不可靠的和使用固定大小(通常很小)缓冲区的数据报服务,为Internet地址族使用UDP。

SOCK_STREAM类型的套接口为全双向的字节流。对于流类套接口,在接收或发送数据前必需处于已连接状态。用connect()调用建立与另一套接口的连接,连接成功后,即可用send()和recv()传送数据。当会话结束后,调用close()。带外数据根据规定用send()和recv()来接收。

Ⅱ linux手册翻译——socket(7)

socket - Linux 套接字接口

本手册页描述了 Linux 网络套接字层用户接口。 套接字是用户进程和内核中网络协议栈之间的统一接口。 协议模块分为协议族(protocol families)(如 AF_INET、AF_IPX 和 AF_PACKET)和套接字类型(socket types)(如 SOCK_STREAM 或 SOCK_DGRAM)。 有关families和types的更多信息,请参阅 socket(2) 。

用户进程使用这些函数来发送或接收数据包以及执行其他套接字操作。 有关更多信息,请参阅它们各自的手册页。

socket(2) 创建套接字,connect(2) 将套接字连接到远程套接字地址,bind(2) 函数将套接字绑定到本地套接字地址,listen(2) 告诉套接字应接受新连接, accept(2) 用于获取具有新传入连接的新套接字。 socketpair(2) 返回两个连接的匿名套接字(仅为少数本地families如 AF_UNIX 实现)

send(2)、sendto(2) 和sendmsg(2) 通过套接字发送数据,而recv(2)、recvfrom(2)、recvmsg(2) 从套接字接收数据。 poll(2) 和 select(2) 等待数据到达或准备好发送数据。 此外,还可以使用 write(2)、writev(2)、sendfile(2)、read(2) 和 readv(2) 等标准 I/O 操作来读取和写入数据。

getsockname(2) 返回本地套接字地址, getpeername(2) 返回远程套接字地址。 getsockopt(2) 和 setsockopt(2) 用于设置或获取套接字层或协议选项。 ioctl(2) 可用于设置或读取一些其他选项。

close(2) 用于关闭套接字。 shutdown(2) 关闭全双工套接字连接的一部分。

套接字不支持使用非零位置查找或调用 pread(2) 或 pwrite(2)。

通过使用 fcntl(2) 在套接字文件描述符上设置 O_NONBLOCK 标志,可以在套接字上执行非阻塞 I/O。 然后所有会阻塞的操作(通常)将返回 EAGAIN(操作应稍后重试); connect(2) 将返回 EINPROGRESS 错误。 然后用户可以通过 poll(2) 或 select(2) 等待各种事件。

如果不使用poll(2) 和 select(2) ,还让内核通过 SIGIO 信号通知应用程序有关事件的信息。 为此,必须通过 fcntl(2) 在套接字文件描述符上设置 O_ASYNC 标志,并且必须通过 sigaction(2) 安装有效的 SIGIO 信号处理程序。 请参阅下面的信号讨论。

每个套接字域(families)都有自己的套接字地址格式,具有特定于域的地址结构。 这些结构的首字段都是整数类型的“家族”字段(类型为 sa_family_t),即指出自己的套接字域或者说是protocol families。 这允许对所有套接字域可以使用统一的系统调用(例如,connect(2)、bind(2)、accept(2)、getsockname(2)、getpeername(2)),并通过套接字地址来确定特定的域。

为了允许将任何类型的套接字地址传递给套接字 API 中的接口,定义了类型 struct sockaddr。 这种类型的目的纯粹是为了允许将特定于域的套接字地址类型转换为“通用”类型,以避免编译器在调用套接字 API 时发出有关类型不匹配的警告。
struct sockaddr 以及在AF_INET常用的地址结构struct sockaddr_in如下所示,sockaddr_in.sin_zero是占位符:

此外,套接字 API 提供了数据类型 struct sockaddr_storage。 这种类型适合容纳所有支持的特定于域的套接字地址结构; 它足够大并且正确对齐。 (特别是它足够大,可以容纳 IPv6 套接字地址。)同struct sockaddr一样,该结构体包括以下字段,可用于标识实际存储在结构体中的套接字地址的类型: sa_family_t ss_family;
sockaddr_storage 结构在必须以通用方式处理套接字地址的程序中很有用(例如,必须同时处理 IPv4 和 IPv6 套接字地址的程序)。

下面列出的套接字选项可以使用setsockopt(2) 设置并使用getsockopt(2) 读取。

当写入已关闭(由本地或远程端)的面向连接的套接字时,SIGPIPE 被发送到写入进程并返回 EPIPE。 当写调用指定 MSG_NOSIGNAL 标志时,不发送信号。

当使用 FIOSETOWN fcntl(2) 或 SIOCSPGRP ioctl(2) 请求时,会在 I/O 事件发生时发送 SIGIO。 可以在信号处理程序中使用 poll(2) 或 select(2) 来找出事件发生在哪个套接字上。 另一种方法(在 Linux 2.2 中)是使用 F_SETSIG fcntl(2) 设置实时信号; 实时信号的处理程序将使用其 siginfo_t 的 si_fd 字段中的文件描述符调用。 有关更多信息,请参阅 fcntl(2)。

在某些情况下(例如,多个进程访问单个套接字),当进程对信号做出反应时,导致 SIGIO 的条件可能已经消失。 如果发生这种情况,进程应该再次等待,因为 Linux 稍后会重新发送信号。

核心套接字网络参数可以通过目录 /proc/sys/net/core/ 中的文件访问。

These operations can be accessed using ioctl(2):

error = ioctl(ip_socket, ioctl_type, &value_result);

Valid fcntl(2) operations:

Linux assumes that half of the send/receive buffer is used for internal kernel structures; thus the values in the corresponding /proc files are twice what can be observed on the wire. Linux will allow port reuse only with the SO_REUSEADDR option when this option was set both in the previous program that performed a bind(2) to the port and in the program that wants to reuse the port. This differs from some implementations (e.g., FreeBSD) where only the later program needs to set the SO_REUSEADDR option. Typically this difference is invisible, since, for example, a server program is designed to always set this option.

Ⅲ linux socket 如何发现主机是否活着

使用基本socket函数来检测。
Linux系统是通过提供套接字(socket)来进行网络编程的。网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符。socket也有一个类似于打
开文件的函数:socket(),调用socket(),该函数返回一个整型的socket的描述符,随后的连接建立、数据传输等操作也都是通过该socket实现。
1、socket函数
syntax:
int socket(int domain, int type, int protocol);
功能说明:
调用成功,返回socket文件描述符;失败,返回-1,并设置errno
参数说明:
domain指明所使用的协议族,通常为PF_INET,表示TCP/IP协议;
type参数指定socket的类型,基本上有三种:数据流套接字、数据报套接字、原始套接字
protocol通常赋值"0"。
两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。socket数据结构中包含这五种信息。
2、bind函数
syntax:
int bind(int sock_fd,struct sockaddr_in *my_addr, int addrlen);
功能说明:
将套接字和指定的端口相连。成功返回0,否则,返回-1,并置errno.
参数说明:
sock_fd是调用socket函数返回值,
my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针;
struct sockaddr_in结构类型是用来保存socket信息的:
struct sockaddr_in {
short int sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
addrlen为sockaddr的长度。
3、connect函数
syntax:
int connect(int sock_fd, struct sockaddr *serv_addr,int addrlen);
功能说明:
客户端发送服务请求。成功返回0,否则返回-1,并置errno。
参数说明:
sock_fd 是socket函数返回的socket描述符;serv_addr是包含远端主机IP地址和端口号的指针;addrlen是结构sockaddr_in的长度。
4、listen函数
syntax:
int listen(int sock_fd, int backlog);
功能说明:
等待指定的端口的出现客户端连接。调用成功返回0,否则,返回-1,并置errno.
参数说明:
sock_fd 是socket()函数返回值;
backlog指定在请求队列中允许的最大请求数
5、accecpt函数
syntax:
int accept(int sock_fd, struct sockadd_in* addr, int addrlen);
功能说明:
用于接受客户端的服务请求,成功返回新的套接字描述符,失败返回-1,并置errno。
参数说明:
sock_fd是被监听的socket描述符,
addr通常是一个指向sockaddr_in变量的指针,
addrlen是结构sockaddr_in的长度。
6、write函数
syntax:
ssize_t write(int fd,const void *buf,size_t nbytes)
功能说明:
write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1. 并设置errno变量.
在网络程序中,当我们向套接字文件描述符写时有俩种可能:
1)write的返回值大于0,表示写了部分或者是全部的数据.
2)返回的值小于0,此时出现了错误.需要根据错误类型来处理.
如果错误为EINTR表示在写的时候出现了中断错误.
如果错误为EPIPE表示网络连接出现了问题.
7、read函数
syntax:
ssize_t read(int fd,void *buf,size_t nbyte)
函数说明:
read函数是负责从fd中读取内容.当读成功时,read返回实际所读的字节数,如果返回的值是0 表示已经读到文件的结束了,小于0表示出现了错误.
如果错误为EINTR说明读是由中断引起的,
如果错误是ECONNREST表示网络连接出了问题.
8、close函数
syntax:
int close(sock_fd);
说明:
当所有的数据操作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据操作:
函数运行成功返回0,否则返回-1

Ⅳ linux 下socket的recv函数返回值问题

说清楚一点,是UDP还是TCP

不管怎么说,在recv之前调用一下select(),检查缓冲到底有没有内容,如果有,再执行recv就不会有任何问题。而且 select的好处是,如果没有接到别的东西,你可以sleep()一下,不占用CPU

用下面的rcv代替你的recv函数吧,我在嵌入式系统开发时自己写的一个标准例程,很可靠:
参数解释:
sck - socket
buf - 接收缓冲区
size-缓冲区大小
time_out-等待时间(按秒计)如果超时则返回
返回值:收到字节数,0表示超时等错误

int rcv(int sck, void * buf, int size, int time_out)
{
if (sck < 1 || !buf || size < 1) return 0;
timeval tv = { 0, 0}; timeval * ptv = 0;
if (time_out > 0) { tv.tv_sec = time_out; ptv = &tv; }
memset(buf, 0, size);
int r = 0; char * b = (char*) buf; int sz = size;
fd_set rd, er; int total = 0; time_t t0 = time(0); time_t t1 = 0;
do {
FD_ZERO(&rd); FD_SET(sck, &rd);
FD_ZERO(&er); FD_SET(sck, &er);
r = select(sck + 1, &rd, 0, &er, ptv);
if (r == -1) { nperror("select()"); return -1; }
if (FD_ISSET(sck, &er)) {
nperror("socket(shutdown)"); return -1;
}//end if
if (FD_ISSET(sck, &rd)) {
r = recv(sck, b, sz, 0);
if (r == -1) { nperror("recv()"); return -1; }
total += r; sz -= r; b+= r;
}//end if
if (time_out > 0)
t1 = time(0) - t0;
else
t1 = time_out - 1;
//end if
}while(sz && t1 < time_out);
return total;
}//end if

Ⅳ linux socket返回的int值是什么 文件描述符一样的东西吗

socket系统调用返回的int值是一个描述符,这个描述符在许多方面都类似于底层的文件描述符,但是和文件描述符又有一些稍微的区别,比如说socket返回的描述符需要用close调用来关闭(这点和文件描述符一样),但是close调用关闭这个描述符时还会有一些不同与文件描述符的行为(因为它代表的是一个套接字连接,所以close调用还会关闭套接字连接和未传输完数据时阻塞)。

Ⅵ 关于Linux下socket编程的问题

recv 函数,不能保证接受到所有你需要的数据包
因此要反复调用recv函数. 并查看函数的返回值
比如,你需要接受5000字节
datalen=0
while datalen<5000
ret=recv(...)
datalen+=ret
....

因为recv这样的特性,所以你并不能保证每次recv收到的数据包是一个完整的, 它可能包含了服务器一次发送数据包的一部分,也可能包括了服务器先后几次发送的几个数据包。因此,你必须自己设计传输协议,能够明确的分辨服务器发送过来的每个数据包(比如每个数据包都有一个明显的结尾,或者数据包头加上数据包的长度)

Ⅶ 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

Ⅷ linux手册翻译——socket(2)


socket - 创建一个用于通信的端点


socket() 创建用于通信的端点并返回引用该端点的文件描述符。 成功调用时返回的文件描述符,将是当前没有被进程打开的所有文件描述符中编号最低的。

domain 参数指定一个通信域; 以决定用于通信的协议族。 这些系列在 <sys/socket.h> 中定义。 目前 Linux 内核理解的格式包括:

当然最常用的当然是 AF_INET ,即IPV4。
上述地址族的更多详细信息以及其他几个地址族的信息可以在 address_families(7) 中找到。

套接字具有指定的 type ,它指定了通信语义。 当前定义的类型有:

某些套接字类型可能不会被所有协议族实现。
从 Linux 2.6.27 开始,type 参数有第二个用途:除了指定套接字类型之外,它还可以包含以下任何值的按位或,以修改 socket() 的行为:

老朋友了,上述两个,第一个是非阻塞,第二个是执行exec时自动关闭。

protocol 指定要与套接字一起使用的特定协议。 通常只存在一个协议来支持给定协议族中的特定套接字类型 ,在这种情况下,protocol 可以指定为 0。但是,可能存在许多协议,在这种情况下,必须在此指定特定协议方式。 特定协议对应的编号可以查看文件: /etc/protocols

SOCK_STREAM 类型的套接字是全双工字节流。 它们不保留记录边界。 流套接字必须处于连接状态,然后才能在其上发送或接收任何数据。 到另一个套接字的连接是通过 connect(2) 调用创建的。 连接后,可以使用 read(2) 和 write(2) 调用或 其变体send(2) 和 recv(2) 的来传输数据。 当会话完成时,可以执行 close(2)。 带外数据也可以按照 send(2) 中的描述进行传输,并按照 recv(2) 中的描述进行接收。

实现 SOCK_STREAM 的通信协议确保数据不会丢失或重复。 如果协议的缓冲空间中存在一条数据在合理的时间内不能成功传输,则认为该连接已失效。 当 SO_KEEPALIVE 在套接字上启用时,将会以特定于协议的方式检查另一端是否仍然存在。 如果进程在损坏的流上发送或接收,则会引发 SIGPIPE 信号; 这会导致不处理信号的进程退出。 SOCK_SEQPACKET 套接字使用与 SOCK_STREAM 套接字相同的系统调用。 唯一的区别是 read(2) 调用将只返回请求的数据量,到达数据包中剩余的其他数据都将被丢弃。 传入数据报中的所有消息边界也被保留。

SOCK_DGRAM 和 SOCK_RAW 套接字允许将数据报发送到在 sendto(2) 调用中指定的通信者。 数据报通常用 recvfrom(2) 接收,它返回下一个数据报及其发送者的地址。

SOCK_PACKET 是一种过时的套接字类型,用于直接从设备驱动程序接收原始数据包。 改用 packet(7)。

An fcntl(2) F_SETOWN operation can be used to specify a process or process group to receive a SIGURG signal when the out-of-band data arrives or SIGPIPE signal when a SOCK_STREAM connection breaks unexpectedly. This operation may also be used to set the process or process group that receives the I/O and asynchronous notification of I/O events via SIGIO. Using F_SETOWN is equivalent to an ioctl(2) call with the FIOSETOWN or SIOCSPGRP argument.

When the network signals an error condition to the protocol mole (e.g., using an ICMP message for IP) the pending error flag is set for the socket. The next operation on this socket will return the error code of the pending error. For some protocols it is possible to enable a per-socket error queue to retrieve detailed information about the error; see IP_RECVERR in ip(7).

套接字的操作由套接字选项控制。 这些选项在 <sys/socket.h> 中定义。 函数setsockopt(2) 和getsockopt(2) 用于设置和获取选项。对于选项的描述,详见socket(7).

成功时,将返回新套接字的文件描述符。 出错时,返回 -1,并设置 errno 以指示错误。


POSIX.1-2001, POSIX.1-2008, 4.4BSD.

The SOCK_NONBLOCK and SOCK_CLOEXEC flags are Linux-specific.

socket() appeared in 4.2BSD. It is generally portable to/from non-BSD systems supporting clones of the BSD socket layer (including System V variants).


在 4.x BSD 下用于协议族的清单常量是 PF_UNIX、PF_INET 等,而 AF_UNIX、AF_INET 等用于地址族。 但是,BSD 手册页已经承诺:“协议族通常与地址族相同”,随后的标准到处都使用 AF_*。

Ⅸ linux socket返回的int值是什么 文件描述符一样的东西吗

对,socket成功建立后,返回值是一个特殊的文件描述符。这个描述符对应的不是物理文件,而是一个socket。
当初,unix在加入socket功能时,将网络传输功能与文件的读写,当做相同的逻辑操作。相应地,将打开socket的返回值,与打开文件的返回值当做逻辑相同的描述符

Ⅹ linux socket阻塞recv怎么返回

recv是socket编程中最常用的函数之一,在阻塞状态的recv有时候会返回不同的值,而对于错误值也有相应的错误码,分别对应不同的状态,下面是我针对常见的几种网络状态的简单总结。
首先阻塞接收的recv有时候会返回0,这仅在对端已经关闭TCP连接时才会发生。
而当拔掉设备网线的时候,recv并不会发生变化,仍然阻塞,如果在这个拔网线阶段,socket被关掉了,后果可能就是recv永久的阻塞了。
所以一般对于阻塞的socket都会用setsockopt来设置recv超时。
当超时时间到达后,recv会返回错误,也就是-1,而此时的错误码是EAGAIN或者EWOULDBLOCK,POSIX.1-2001上允许两个任意一个出现都行,所以建议在判断错误码上两个都写上。
如果socket是被对方用linger为0的形式关掉,也就是直接发RST的方式关闭的时候,recv也会返回错误,错误码是ENOENT
还有一种经常在代码中常见的错误码,那就是EINTER,意思是系统在接收的时候因为收到其他中断信号而被迫返回,不算socket故障,应该继续接收。但是这种情况非常难再现,我尝试过一边一直在不停的发信号,一边用recv接收数据,也没有出现过。这种异常错误我附近只有一个朋友在用write的时候见到过一次,但是总是会有概率出现的,所以作为完善的程序必须对此错误进行特殊处理。
一般设置超时的阻塞recv常用的方法都如下:
while(1)
{
cnt = (int)recv(m_socket, pBuf,RECVSIZE, 0);
if( cnt >0 )
{
//正常处理数据
}
else
{
if((cnt<0) &&(errno == EAGAIN||errno == EWOULDBLOCK||errno == EINTR)) //这几种错误码,认为连接是正常的,继续接收
{
continue;//继续接收数据
}
break;//跳出接收循环
}
}
阻塞与非阻塞recv返回值没有区分,都是 <0 出错 =0 连接关闭 >0 接收到数据大小。

Linux环境下,须如下定义:struct timeval timeout = {3,0};
//设置发送超时
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
//设置接收超时
setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));

热点内容
主播网站源码 发布:2025-05-15 02:50:56 浏览:167
中文编程语言有哪些 发布:2025-05-15 02:48:59 浏览:535
配置中心应急流程有哪些 发布:2025-05-15 02:37:31 浏览:669
php宏定义 发布:2025-05-15 02:32:54 浏览:270
咸鱼支付密码哪里改 发布:2025-05-15 02:32:53 浏览:520
存储机箱 发布:2025-05-15 02:31:31 浏览:836
编程很累吗 发布:2025-05-15 02:29:25 浏览:552
疫情期间访问国外网络 发布:2025-05-15 02:24:24 浏览:247
我的世界网易版游戏服务器 发布:2025-05-15 02:23:46 浏览:221
全球编程网站 发布:2025-05-15 02:22:55 浏览:334