linuxsocket函數
① 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)linuxsocket函數擴展閱讀:
支持下述類型描述:
SOCK_STREAM 提供有序的、可靠的、雙向的和基於連接的位元組流,使用帶外數據傳送機制,為Internet地址族使用TCP。
SOCK_DGRAM 支持無連接的、不可靠的和使用固定大小(通常很小)緩沖區的數據報服務,為Internet地址族使用UDP。
SOCK_STREAM類型的套介面為全雙向的位元組流。對於流類套介面,在接收或發送數據前必需處於已連接狀態。用connect()調用建立與另一套介面的連接,連接成功後,即可用send()和recv()傳送數據。當會話結束後,調用close()。帶外數據根據規定用send()和recv()來接收。
② 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是什麼意思
基於Linux的SOCKET編程。
④ 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編程中close()函數
不可以,調用close後底層會四次握手,連接中斷,句柄已經不可用了
⑥ 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編程中send函數如何強制其將數據發出去
在多線程編程中其中使用一個線程來accept要連接的客戶端。同時在接受client的請求之後新建一個線程來進行具體的操作。其操作包括向client端發送一定位元組的數據,使用send()函數來進行操作。如果在發送過程中出現任何一個client端的斷線,則整個程序都會退出。
ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags);
關於Linux命令的介紹,看看《linux就該這么學》,具體關於這一章地址3w(dot)linuxprobe/chapter-02(dot)html
上面為send函數原型,在通常的使用中flags參數一般設置為0.此時如果客戶端斷開,繼續往裡邊寫數據的話,會引發一個信號SIGPIPE,此信號會引發線程的退出、
解決的方法:1)可以將flags參數設置為MSG_NOSIGNAL。2)設置SIG_IGN信號處理函數。
⑧ linux下socket編程中close()函數
只要不用close或fclose,不管把這個socket_fd值存到哪裡,都可以使用。比如:
int
socket_fd
=
socket(...);
int
socket_x
=
socket_fd;
那麼send(socket_x)和send(socket_fd)結果完全一致
⑨ Linux C中的Socket,shutdown函數和close函數有什麼不同
假設server和client 已經建立了連接,server調用了close, 發送FIN 段給client(其實不一定會發送FIN段,後面再說),此時server不能再通過socket發送和接收數據,此時client調用read,如果接收到FIN 段會返回0,但client此時還是可以write 給server的,write調用只負責把數據交給TCP發送緩沖區就可以成功返回了,所以不會出錯,而server收到數據後應答一個RST段,表示伺服器已經不能接收數據,連接重置,client收到RST段後無法立刻通知應用層,只把這個狀態保存在TCP協議層。如果client再次調用write發數據給server,由於TCP協議層已經處於RST狀態了,因此不會將數據發出,而是發一個SIGPIPE信號給應用層,SIGPIPE信號的預設處理動作是終止程序。有時候代碼中需要連續多次調用write,可能還來不及調用read得知對方已關閉了連接就被SIGPIPE信號終止掉了,這就需要在初始化時調用sigaction處理SIGPIPE信號,對於這個信號的處理我們通常忽略即可,signal(SIGPIPE, SIG_IGN); 如果SIGPIPE信號沒有導致進程異常退出,write返回-1並且errno為EPIPE。 #include intclose(int fd);close 關閉了自身數據傳輸的兩個方向。 #include intshutdown(int sockfd, int how);shutdown 可以選擇關閉某個方向或者同時關閉兩個方向,shutdownhow = 1 or how = 2 (SHUT_WR or SHUT_RDWR),可以保證對等方接收到一個EOF字元(即發送了一個FIN段),而不管其他進程是否已經打開了這個套接字。而close不能保證,只有當某個sockfd的引用計數為0,close 才會發送FIN段,否則只是將引用計數減1而已。也就是說只有當所有進程(可能fork多個子進程都打開了這個套接字)都關閉了這個套接字,close 才會發送FIN段。所以說,如果是調用shutdown how = 1 ,則意味著往一個已經接收FIN的套接字中寫是允許的,接收到FIN段僅代表對方不再發送數據,但對方還是可以讀取數據的,可以讓對方可以繼續讀取緩沖區剩餘的數據。下面使用shutdown 修改客戶端程序,在前面講過的使用select函數修改後的客戶端程序基礎上,修改很小一部分:C++ Codeif (FD_ISSET(fd_stdin, &rset)){if (fgets(sendbuf, sizeof(sendbuf), stdin)== NULL){stdineof = 1; //表示已經輸入完畢/* 關閉sock的寫端,還能夠接收數據,在sock的緩沖區末尾添加一個FIN段 */shutdown(sock, SHUT_WR);}else{writen(sock, sendbuf, strlen(sendbuf));memset(sendbuf, 0, sizeof(sendbuf));}}為了測試我們想要的效果,需要在select函數修改後的伺服器端程序的 134 行代碼之後,即writen 之前 sleep(4); 目的是接收到客戶端數據後不馬上回射回去,睡眠4s 後在客戶端已經關閉連接的情況下再發送數據。先運行伺服器端程序,再運行客戶端程序,在客戶端標准輸入,迅速敲入兩行:AAAAA
BBBBB
然後按下ctrl+d 即fgets 會返回NULL,然後調用shutdown關閉寫端,雖然伺服器端延時才發送數據,此時客戶端寫端已經關閉,但還是可以讀取到回射回來的數據,伺服器端最後得到一個FIN段,read返回0,列印輸出 client close ,並且close(conn); 而客戶端在讀取服務端回射回來的兩次數據後,再次read 也返回0,故列印 server connectclose,break退出循環,進程順利退出。從下面的輸出還可以看出,因為延時的關系,所以不像以前那樣發射一行就回射一行。simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$./echoser_selectrecv connect ip=127.0.0.1 port=54010fdsgfgdgfedgclient close...........................simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$./echocli_select_shutdownlocal ip=127.0.0.1 port= connect close如果我們將客戶端程序中的shutdown 改成了 close,那麼當延時後伺服器端發送數據給客戶端時,客戶端的讀端和寫端都已經關閉,第一次發AAAAA會返回一個RST段,根據本文前面所說,再次發BBBBB直接產生SIGPIPE信號,默認會終止進程,但因為我們已經設置了忽略SIGPIPE信號,所以伺服器端進程不會被終止,但客戶端也會出錯,因為回到while循環開頭,select阻塞等待時發現套接字的讀端已經關閉,所以不能再關心可讀事件了,select會返回-1,錯誤碼是 EBADF: Bad File Descriptor。Linux C中的Socket,shutdown函數和close函數有什麼不同
