① linux下的socket是怎麼回事,如何利用其實現區域網內的數據處理
//服務端server.c
#include
<stdio.h>
#include
<stdlib.h>
#include
<errno.h>
#include
<string.h>
#include
<sys/types.h>
#include
<netinet/in.h>
#include
<sys/socket.h>
#include
<sys/wait.h>
#define
SERVPORT
6000
/*伺服器監聽埠號
*/
#define
BACKLOG
10
/*
最大同時連接請求數
*/
#define
MAXDATASIZE
100
main()
{
char
buf[MAXDATASIZE];
int
sockfd,client_fd;
/*sock_fd:監聽socket;client_fd:數據傳輸socket
*/
struct
sockaddr_in
my_addr;
/*
本機地址信息
*/
struct
sockaddr_in
remote_addr;
/*
客戶端地址信息
*/
if
((sockfd
=
socket(AF_INET,
SOCK_STREAM,
0))
==
-1)
{
perror("socket創建出錯!");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr
=
INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if
(bind(sockfd,
(struct
sockaddr
*)&my_addr,
sizeof(struct
sockaddr))
==
-1)
{
perror("bind出錯!");
exit(1);
}
if
(listen(sockfd,
BACKLOG)
==
-1)
{
perror("listen出錯!");
exit(1);
}
while(1)
{
sin_size
=
sizeof(struct
sockaddr_in);
if
((client_fd
=
accept(sockfd,
(struct
sockaddr
*)&remote_addr,
&sin_size))
==
-1)
{
perror("accept出錯");
continue;
}
printf("received
a
connection
from
%s\n",
inet_ntoa(remote_addr.sin_addr));
if
(!fork())
{
/*
子進程代碼段
*/
if
((recvbytes=recv(client_fd,
buf,
MAXDATASIZE,
0))
==-1)
{
perror("recv出錯!");
close(client_fd);
exit(0);
}
buf[recvbytes]
=
'\0';
printf("from
client
Received:
%s",buf);
if
(send(client_fd,
"thanks!\n",
8,
0)
==
-1)
perror("send出錯!");
close(client_fd);
exit(0);
}
close(client_fd);
}
}
//客戶端client.c
#include<stdio.h>
#include
<stdlib.h>
#include
<errno.h>
#include
<string.h>
#include
<netdb.h>
#include
<sys/types.h>
#include
<netinet/in.h>
#include
<sys/socket.h>
#define
SERVPORT
6000
#define
MAXDATASIZE
100
main(int
argc,
char
*argv[])
{
int
sockfd,
recvbytes;
char
buf[MAXDATASIZE];
struct
hostent
*host;
struct
sockaddr_in
serv_addr;
if
(argc
<
2)
{
fprintf(stderr,"Please
enter
the
server's
hostname!\n");
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL)
{
herror("gethostbyname出錯!");
exit(1);
}
if
((sockfd
=
socket(AF_INET,
SOCK_STREAM,
0))
==
-1)
{
perror("socket創建出錯!");
exit(1);
}
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr
=
*((struct
in_addr
*)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
if
(connect(sockfd,
(struct
sockaddr
*)&serv_addr,
sizeof(struct
sockaddr))
==
-1)
{
perror("connect出錯!");
exit(1);
}
if
(send(sockfd,
"hello!\n",
7,
0)
==
-1)
{
perror("send出錯!");
exit(1);
}
if
((recvbytes=recv(sockfd,
buf,
MAXDATASIZE,
0))
==-1)
{
perror("recv出錯!");
exit(1);
}
buf[recvbytes]
=
'\0';
printf("Received:
%s",buf);
close(sockfd);
}
② 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執行體為你管理描述符表。
(2)linuxsocket詳解擴展閱讀:
支持下述類型描述:
SOCK_STREAM 提供有序的、可靠的、雙向的和基於連接的位元組流,使用帶外數據傳送機制,為Internet地址族使用TCP。
SOCK_DGRAM 支持無連接的、不可靠的和使用固定大小(通常很小)緩沖區的數據報服務,為Internet地址族使用UDP。
SOCK_STREAM類型的套介面為全雙向的位元組流。對於流類套介面,在接收或發送數據前必需處於已連接狀態。用connect()調用建立與另一套介面的連接,連接成功後,即可用send()和recv()傳送數據。當會話結束後,調用close()。帶外數據根據規定用send()和recv()來接收。
③ Window和Linux下Socket的區別
socket編程在windows和linux下的區別有以下幾點銷租培:1)頭文件windows下winsock.h或winsock2.hlinux下netinet/in.h(大部分都在這兒),unistd.h(close函數在這兒),sys/socket.h(在in.h里已經包含了,可以省了)2)初始化windows下需要用WSAStartup啟動Ws2_32.lib,並且要用#pragmacomment(lib,"Ws2_32")來告知編譯器鏈接該lib。linux下不需要3)關閉socketwindows下closesocket()linux下close()4)類型windows下SOCKETlinux下int(我喜歡用long,這樣保證是4byte,因為-1我總喜歡寫成0xFFFF)5)獲取錯誤碼windows下getlasterror()/WSAGetLastError()linux下,未能成功執行的socket操作虧唯會返回-1;如果包含了errno.h,就會設置errno變數6)設置非阻塞windows下ioctlsocket()linux下fcntl(),需要頭文件fcntl.h7)send函數最後一個參數windows下一般設置為0linux下最好設置為MSG_NOSIGNAL,如果不設置,在發送出錯後有可能會導致程序退出8)毫秒級時間獲取windows下GetTickCount()linux下gettimeofday()9)多線程windows下包含process.h,使用_beginthread和_endthreadlinux下包含pthread.h,使用pthread_create和pthread_exit10)用IP定義一個地址(sockaddr_in的結構的區別)windows下addr_var.sin_addr.S_un.S_addrlinux下addr_var.sin_addr.s_addr而且Winsock里最後那個32bit的S_addr也有幾個以聯合(Union)的形式與它共享內存空間的成員變數(便於以其他方式賦值),而Linux的Socket沒有這個聯合,就是一個32bit的s_addr。遇到那種得到了是4個char的IP的形式(比如127一個,0一個,0一個和1一個共四個char),WinSock可以直接用4個S_b來賦值到S_addr里,而在Linux下,可以用邊向左移位(一下8bit,共四下)邊相加的方法賦值。11)異常處理linux下當連接斷開,還發數據的時候,不僅send()的返型戚回值會有反映,而且還會像系統發送一個異常消息,如果不作處理,系統會出BrokePipe,程序會退出。為此,send()函數的最後一個參數可以設MSG_NOSIGNAL,禁止send()函數向系統發送異常消息。
④ Linux下socket並發連接數怎麼設置
並發socket連接數的多少決定於系統資源的多少,沒有一個常值的.在實際開發或者linux系統管理中也會根據需要進行相應的設置.
1.一般來說每一個網路連接,都會建立相應的socket句柄,同時每個連接也會有標准輸入輸出等基本的文件文件句柄,而且每一個socket連接都是進行文件操作的,因此連接數決定於系統資源.
2.Linux上一般可以通過ulimit來進行相應的資源限制,默認能打開的文件描述符自己可以查看.如下圖所示:
3.ulimit的命令格式:ulimit [-acdfHlmnpsStvw] [size]
參數說明:
-H 設置硬資源限制.
-S 設置軟資源限制.
-a 顯示當前所有的資源限制.
-c size:設置core文件的最大值.單位:blocks
-d size:設置數據段的最大值.單位:kbytes
-f size:設置創建文件的最大值.單位:blocks
-l size:設置在內存中鎖定進程的最大值.單位:kbytes
-m size:設置可以使用的常駐內存的最大值.單位:kbytes
-n size:設置內核可以同時打開的文件描述符的最大值.單位:n
-p size:設置管道緩沖區的最大值.單位:kbytes
-s size:設置堆棧的最大值.單位:kbytes
-t size:設置CPU使用時間的最大上限.單位:seconds
-v size:設置虛擬內存的最大值.單位:kbytes
-u <程序數目> 用戶最多可開啟的程序數目
⑤ linux 中sock是什麼意思
你所說的 sock 不就是socket嘛~~,你把你所說的上面那段話中sock 全部替換成socket 就一下都讀明白了。 至於linux中sock,它一般是指通過shell編程後形成的套介面文件,通過ls -l 後,第一個顯示的文件類型為:s 。
至於socket ,你應該已經很明白了吧,說白了就是一個通信管道。
我擦 ,怎麼都2007年的問題了,居然 在我的最新問題中顯示出來了~~我勒個去
⑥ linux中socket是如何調用驅動程序
在 Linux 中包括內嵌的協議 TCP、UDP,當然還有 IP。然後是另外一個協議無關層,提供回了與各個設答備驅動程序通信的通用介面,最下面是設備驅動程序本身。
Linux 中的 socket 結構是 struct sock,這個結構是在 linux/include/net/sock.h 中定義的。這個巨大的結構中包含了特定 socket 所需要的所有狀態信息,其中包括 socket 所使用的特定協議和在 socket 上可以執行的一些操作。
網路子系統可以通過一個定義了自己功能的特殊結構來了解可用協議。每個協議都維護了一個名為 proto 的結構(可以在 linux/include/net/sock.h 中找到)。這個結構定義了可以在從 socket 層到傳輸層中執行特定的 socket 操作(例如,如何創建一個 socket,如何使用 socket 建立一個連接,如何關閉一個 socket 等等)。
⑦ 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和sock結構體的區別
//**************************************************************************
/* 1、每一個打開的文件、socket等等都用一個file數據結構代表,這樣文件和socket就通過inode->u(union)中的各個成員來區別:
struct inode {
.....................
union {
struct ext2_inode_info ext2_i;
struct ext3_inode_info ext3_i;
struct socket socket_i;
.....................
} u; };
2、每個socket數據結構都有一個sock數據結構成員,sock是對socket的擴充,兩者一一對應,socket->sk指向對應的sock,sock->socket
指向對應的socket;
3、socket和sock是同一事物的兩個側面,為什麼不把兩個數據結構合並成一個呢?這是因為socket是inode結構中的一部分,即把inode結
構內部的一個union用作socket結構。由於插口操作的特殊性,這個數據結構中需要有大量的結構成分,如果把這些成分全部放到socket
結構中,則inode結構中的這個union就會變得很大,從而inode結構也會變得很大,而對於其他文件系統這個union是不需要這么大的,
所以會造成巨大浪費,系統中使用inode結構的數量要遠遠超過使用socket的數量,故解決的辦法就是把插口分成兩部分,把與文件系
統關系密切的放在socket結構中,把與通信關系密切的放在另一個單獨結構sock中;
*/
struct socket
{
socket_state state; // 該state用來表明該socket的當前狀態
typedef enum {
SS_FREE = 0, /* not allocated */
SS_UNCONNECTED, /* unconnected to any socket */
SS_CONNECTING, /* in process of connecting */
SS_CONNECTED, /* connected to socket */
SS_DISCONNECTING /* in process of disconnecting */
} socket_state;
unsigned long flags; //該成員可能的值如下,該標志用來設置socket是否正在忙碌
#define SOCK_ASYNC_NOSPACE 0
#define SOCK_ASYNC_WAITDATA 1
#define SOCK_NOSPACE 2
struct proto_ops *ops; //依據協議邦定到該socket上的特定的協議族的操作函數指針,例如IPv4 TCP就是inet_stream_ops
struct inode *inode; //表明該socket所屬的inode
struct fasync_struct *fasync_list; //非同步喚醒隊列
struct file *file; //file回指指針
struct sock *sk; //sock指針
wait_queue_head_t wait; //sock的等待隊列,在TCP需要等待時就sleep在這個隊列上
short type; //表示該socket在特定協議族下的類型例如SOCK_STREAM,
unsigned char passcred; //在TCP分析中無須考慮
};
⑨ linux socket是什麼意思
socket介面是TCP/IP網路的API,socket介面定義了許多函數或常式,程序員可以用它們來開發TCP/IP網路上的應用程序。要學Internet上的TCP/IP網路編程,必須理解socket介面。
socket介面設計者最先是將介面放在Unix操作系統裡面的。如果了解Unix系統的輸入和輸出的話,就很容易了解socket了。網路的 socket數據傳輸是一種特殊的I/O,socket也是一種文件描述符。socket也具有一個類似於打開文件的函數調用socket(),該函數返回一個整型的socket描述符,隨後的連接建立、數據傳輸等操作都是通過該socket實現的。常用的socket類型有兩種:流式socket (SOCK_STREAM)和數據報式socket(SOCK_DGRAM)。流式是一種面向連接的socket,針對於面向連接的TCP服務應用;數據報式socket是一種無連接的socket,對應於無連接的UDP服務應用。
socket建立
為了建立socket,程序可以調用socket函數,該函數返回一個類似於文件描述符的句柄。socket函數原型為:
int socket(int domain, int type, int protocol); domain指明所使用的協議族,通常為PF_INET,表示互聯網協議族(TCP/IP協議族);type參數指定socket的類型: SOCK_STREAM 或SOCK_DGRAM,socket介面還定義了原始socket(SOCK_RAW),允許程序使用低層協議;protocol通常賦值 "0"。 socket()調用返回一個整型socket描述符,你可以在後面的調用使用它。
socket描述符是一個指向內部數據結構的指針,它指向描述符表入口。調用socket函數時,socket執行體將建立一個socket,實際上 "建立一個socket"意味著為一個socket數據結構分配存儲空間。socket執行體為你管理描述符表。 兩個網路程序之間的一個網路連接包括五種信息:通信協議、本地協議地址、本地主機埠、遠端主機地址和遠端協議埠。socket數據結構中包含這五種信息。
socket配置
通過socket調用返回一個socket描述符後,在使用socket進行網路傳輸以前,必須配置該socket。面向連接的socket客戶端通過調用connect函數在socket數據結構中保存本地和遠端信息。無連接socket的客戶端和服務端以及面向連接socket的服務端通過調用 bind函數來配置本地信息。
bind函數將socket與本機上的一個埠相關聯,隨後你就可以在該埠監聽服務請求。bind函數原型為:
int bind(int sockfd,struct sockaddr*my_addr, int addrlen); Sockfd是調用socket函數返回的socket描述符,my_addr是一個指向包含有本機IP地址及埠號等信息的sockaddr類型的指針;addrlen常被設置為sizeof(struct sockaddr)。
struct sockaddr結構類型是用來保存socket信息的:
struct sockaddr {
unsigned short sa_family; /*地址族,AF_xxx*/ char sa_data[14]; /*14位元組的協議地址*/ };
sa_family一般為AF_INET,代表Internet(TCP/IP)地址族;sa_data則包含該socket的IP地址和埠號。 另外還有一種結構類型: struct sockaddr_in {
short int sin_family; /*地址族*/
unsigned short int sin_port; /*埠號*/ struct in_addr sin_addr; /*IP地址*/
unsigned char sin_zero[8];/*填0保持與sockaddr同樣大小*/ };
這個結構更方便使用。sin_zero用來將sockaddr_in結構填充到與struct sockaddr同樣的長度,可以用bzero()或memset()函數將其置為零。指向
sockaddr_in 的指針和指向sockaddr的指針可以相互轉換,這意味著如果一個函數所需參數類型是sockaddr時,你可以在函數調用的時候將一個指向 sockaddr_in的指針轉換為指向sockaddr的指針;或者相反。 使用bind函數時,可以用下面的賦值實現自動獲得本機IP地址和隨機獲取一個沒有被佔用的埠號:
my_addr.sin_port=0; /* 系統隨機選擇一個未被使用的埠號*/ my_addr.sin_addr.s_addr=INADDR_ANY; /* 填入本機IP地址*/
通過將my_addr.sin_port置為0,函數會自動為你選擇一個未佔用的埠來使用。同樣,通過將my_addr.sin_addr.s_addr置為INADDR_ANY,系統會自動填入本機IP地址。
注意在使用bind函數是需要將sin_port和sin_addr轉換成為網路位元組優先順序;而sin_addr則不需要轉換。
計算機數據存儲有兩種位元組優先順序:高位位元組優先和低位位元組優先。Internet上數據以高位位元組優先順序在網路上傳輸,所以對於在內部是以低位位元組優先方式存儲數據的機器,在Internet上傳輸數據時就需要進行轉換,否則就會出現數據不一致。
htonl():把32位值從主機位元組序轉換成網路位元組序 htons():把16位值從主機位元組序轉換成網路位元組序 ntohl():把32位值從網路位元組序轉換成主機位元組序 ntohs():把16位值從網路位元組序轉換成主機位元組序
bind()函數在成功被調用時返回0;出現錯誤時返回 "-1"並將errno置為相應的錯誤號。需要注意的是,在調用bind函數時一般不要將埠號置為小於1024的值,因為1到1024是保留埠號,你可以選擇大於1024中的任何一個沒有被佔用的埠號。
連接建立
面向連接的客戶程序使用connect函數來配置socket並與遠端伺服器建立一個TCP連接,其函數原型為:
int connect(int sockfd, struct sockaddr*serv_addr,int addrlen); Sockfd 是socket函數返回的socket描述符;serv_addr是包含遠端主機IP地址和埠號的指針;addrlen是遠端地質結構的長度。 connect函數在出現錯誤時返回-1,並且設置errno為相應的錯誤碼。
進行客戶端程序設計無須調用bind(),因為這種情況下只需知道目的機器的IP地址,而客戶通過哪個埠與伺服器建立連接並不需要關心,socket執行體為你的程序自動選擇一個未被佔用的埠,並通知你的程序數據什麼時候到達埠。
connect函數啟動和遠端主機的直接連接。只有面向連接的客戶程序使用socket時才需要將此socket與遠端主機相連。無連接協議從不建立直接連接。面向連接的伺服器也從不啟動一個連接,它只是被動的在協議埠監聽客戶的請求。
listen函數使socket處於被動的監聽模式,並為該socket建立一個輸入數據隊列,將到達的服務請求保存在此隊列中,直到程序處理它們。 int listen(int sockfd, int backlog);
Sockfd 是socket系統調用返回的socket 描述符;backlog指定在請求隊列中允許的最大請求數,進入的連接請求將在隊列中等待accept()它們(參考下文)。Backlog對隊列中等待服務的請求的數目進行了限制,大多數系統預設值為20。如果一個服務請求到來時,輸入隊列已滿,該socket將拒絕連接請求,客戶將收到一個出錯信息。
當出現錯誤時listen函數返回-1,並置相應的errno錯誤碼。
accept()函數讓伺服器接收客戶的連接請求。在建立好輸入隊列後,伺服器就調用accept函數,然後睡眠並等待客戶的連接請求。 int accept(int sockfd, void*addr, int*addrlen);
sockfd是被監聽的socket描述符,addr通常是一個指向sockaddr_in變數的指針,該變數用來存放提出連接請求服務的主機的信息(某台主機從某個埠發出該請求);addrten通常為一個指向值為sizeof(struct sockaddr_in)的整型指針變數。出現錯誤時accept函數返回-1並置相應的errno值。 首先,當accept函數監視的 socket收到連接請求時,socket執行體將建立一個新的socket,執行體將這個新socket和請求連接進程的地址聯系起來,收到服務請求的初始socket仍可以繼續在以前的 socket上監聽,同時可以在新的socket描述符上進行數據傳輸操作。 數據傳輸
send()和recv()這兩個函數用於面向連接的socket上進行數據傳輸。 int send(int sockfd, const void*msg, int len, int flags);
Sockfd是你想用來傳輸數據的socket描述符;msg是一個指向要發送數據的指針;Len是以位元組為單位的數據的長度;flags一般情況下置為0(關於該參數的用法可參照man手冊)。
send()函數返回實際上發送出的位元組數,可能會少於你希望發送的數據。在程序中應該將send()的返回值與欲發送的位元組數進行比較。當send()返回值與len不匹配時,應該對這種情況進行處理。
int recv(int sockfd,void*buf,int len,unsigned int flags);