函數(shù)說明:socket()用來建立一個新的socket, 也就是向系統(tǒng)注冊, 通知系統(tǒng)建立一通信端口. 參數(shù)domain 指定使用何種的地址類型, 完整的定義在/usr/include/bits/socket.h 內(nèi), 底下是常見的協(xié)議:
創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站制作、成都網(wǎng)站設(shè)計與策劃設(shè)計,岫巖網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:岫巖等地區(qū)。岫巖做網(wǎng)站價格咨詢:028-86922220
PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX 進程通信協(xié)議
PF_INET?AF_INET Ipv4 網(wǎng)絡(luò)協(xié)議
PF_INET6/AF_INET6 Ipv6 網(wǎng)絡(luò)協(xié)議
PF_IPX/AF_IPX IPX-Novell 協(xié)議
PF_NETLINK/AF_NETLINK 核心用戶接口裝置
PF_X25/AF_X25 ITU-T X. 25/ISO-8208 協(xié)議
PF_AX25/AF_AX25 業(yè)余無線AX. 25 協(xié)議
PF_ATMPVC/AF_ATMPVC 存取原始 ATM PVCs
PF_APPLETALK/AF_APPLETALK appletalk (DDP)協(xié)議
PF_PACKET/AF_PACKET 初級封包接口
參數(shù) type 有下列幾種數(shù)值:
1、SOCK_STREAM 提供雙向連續(xù)且可信賴的數(shù)據(jù)流, 即TCP. 支持 OOB 機制, 在所有數(shù)據(jù)傳送前必須使用connect()來建立連線狀態(tài).
2、SOCK_DGRAM 使用不連續(xù)不可信賴的數(shù)據(jù)包連接
3、SOCK_SEQPACKET 提供連續(xù)可信賴的數(shù)據(jù)包連接
4、SOCK_RAW 提供原始網(wǎng)絡(luò)協(xié)議存取
5、SOCK_RDM 提供可信賴的數(shù)據(jù)包連接
6、SOCK_PACKET 提供和網(wǎng)絡(luò)驅(qū)動程序直接通信. protocol 用來指定socket 所使用的傳輸協(xié)議編號, 通常此參考不用管它, 設(shè)為0 即可.
返回值:成功則返回socket 處理代碼, 失敗返回-1.
錯誤代碼:
1、EPROTONOSUPPORT 參數(shù)domain 指定的類型不支持參數(shù)type 或protocol 指定的協(xié)議
2、ENFILE 核心內(nèi)存不足, 無法建立新的socket 結(jié)構(gòu)
3、EMFILE 進程文件表溢出, 無法再建立新的socket
4、EACCESS 權(quán)限不足, 無法建立type 或protocol 指定的協(xié)議
5、ENOBUFS/ENOMEM 內(nèi)存不足
6、EINVAL 參數(shù)domain/type/protocol 不合法
誰能告訴我accept()函數(shù)返回一個新的套接字,所謂新套接字就是說這個是新產(chǎn)生的套接字,并不是你用來accept的那個監(jiān)聽的套接字。
accept()函數(shù)用于一個套接口接受一個連接。accept()是c語言中網(wǎng)絡(luò)編程的重要的函數(shù),windows系統(tǒng)在#includewinsock.h ,而linux系統(tǒng)在#include sys/socket.h中。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
參數(shù)
sockfd:套接口描述字,該套接口在listen()后監(jiān)聽連接。
addr:(可選)指針,指向一緩沖區(qū),其中接收為通訊層所知的連接實體的地址。Addr參數(shù)的實際格式由套接口創(chuàng)建時所產(chǎn)生的地址族確定。
addrlen:(可選)指針,輸入?yún)?shù),配合addr一起使用,指向存有addr地址長度的整型數(shù)。
實例:
#ifndef UNICODE
#defineUNICODE
#endif
#include winsock2.h
#include stdio.h
#include windows.h
#pragmacomment(lib,"Ws2_32.lib")
int wmain(void)
{
WSADATAwsaData ;
intiResult=WSAStartup(MAKEWORD(2,2),wsaData);
if(iResult!=NO_ERROR)
{
wprintf(L "WSAStartupfailedwitherror:%ld\n",iResult);
return 1 ;
}
SOCKETListenSocket ;
ListenSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(ListenSocket==INVALID_SOCKET)
{
wprintf(L "socketfailedwitherror:%ld\n",WSAGetLastError());
WSACleanup();
return 1 ;
}
sockaddr_inservice ;
service.sin_family=AF_INET ;
service.sin_addr.s_addr=inet_addr("127.0.0.1");
service.sin_port=htons(27015);
if(bind(ListenSocket,
(SOCKADDR*)service,sizeof(service))==SOCKET_ERROR)
{
wprintf(L"bindfailedwitherror:%ld\n",WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1 ;
}
if(listen(ListenSocket,1)==SOCKET_ERROR)
{
wprintf(L"listenfailedwitherror:%ld\n",WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1 ;
}
SOCKETAcceptSocket ;
wprintf(L "Waitingforclienttoconnect...\n");
AcceptSocket=accept(ListenSocket,NULL,NULL);
if(AcceptSocket==INVALID_SOCKET)
{
wprintf(L "accept failed with error:%ld\n",WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1 ;
}
else
wprintf(L "Clientconnected.\n");
//Nolongerneedserversocket
closesocket(ListenSocket);
WSACleanup();
return 0 ;
}
如果你要編寫的是一個服務(wù)程序,那么先調(diào)用socket()創(chuàng)建一個套接字,然后調(diào)用bind()綁定ip地址和端口,再然后啟動一個死循環(huán),循環(huán)中調(diào)用accept()接受連接,對于每個接受的連接,可以起線程進行處理,在線程中調(diào)用send()、recv()發(fā)送和接收數(shù)據(jù)。
如果你要編寫的是一個客戶端程序,那么就簡單多了,先調(diào)用socket()創(chuàng)建一個套接字,然后調(diào)用connect()連接服務(wù)器,之后就是調(diào)用send()、recv()發(fā)送和接收數(shù)據(jù)了。
#include stdio.h
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
int main(int argc, char *argv[])
{
int server_sockfd;//服務(wù)器端套接字
int client_sockfd;//客戶端套接字
int len;
struct sockaddr_in my_addr; //服務(wù)器網(wǎng)絡(luò)地址結(jié)構(gòu)體
struct sockaddr_in remote_addr; //客戶端網(wǎng)絡(luò)地址結(jié)構(gòu)體
int sin_size;
char buf[BUFSIZ]; //數(shù)據(jù)傳送的緩沖區(qū)
memset(my_addr,0,sizeof(my_addr)); //數(shù)據(jù)初始化--清零
my_addr.sin_family=AF_INET; //設(shè)置為IP通信
my_addr.sin_addr.s_addr=INADDR_ANY;//服務(wù)器IP地址--允許連接到所有本地地址上
my_addr.sin_port=htons(8000); //服務(wù)器端口號
/*創(chuàng)建服務(wù)器端套接字--IPv4協(xié)議,面向連接通信,TCP協(xié)議*/
if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))0)
{
perror("socket");
return 1;
}
/*將套接字綁定到服務(wù)器的網(wǎng)絡(luò)地址上*/
if (bind(server_sockfd,(struct sockaddr *)my_addr,sizeof(struct sockaddr))0)
{
perror("bind");
return 1;
}
/*監(jiān)聽連接請求--監(jiān)聽隊列長度為5*/
listen(server_sockfd,5);
sin_size=sizeof(struct sockaddr_in);
/*等待客戶端連接請求到達*/
if((client_sockfd=accept(server_sockfd,(struct sockaddr *)remote_addr,sin_size))0)
{
perror("accept");
return 1;
}
printf("accept client %s/n",inet_ntoa(remote_addr.sin_addr));
len=send(client_sockfd,"Welcome to my server/n",21,0);//發(fā)送歡迎信息
/*接收客戶端的數(shù)據(jù)并將其發(fā)送給客戶端--recv返回接收到的字節(jié)數(shù),send返回發(fā)送的字節(jié)數(shù)*/
while((len=recv(client_sockfd,buf,BUFSIZ,0))0))
{
buf[len]='/0';
printf("%s/n",buf);
if(send(client_sockfd,buf,len,0)0)
{
perror("write");
return 1;
}
}
close(client_sockfd);
close(server_sockfd);
return 0;
}
#include stdio.h
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
int main(int argc, char *argv[])
{
int client_sockfd;
int len;
struct sockaddr_in remote_addr; //服務(wù)器端網(wǎng)絡(luò)地址結(jié)構(gòu)體
char buf[BUFSIZ]; //數(shù)據(jù)傳送的緩沖區(qū)
memset(remote_addr,0,sizeof(remote_addr)); //數(shù)據(jù)初始化--清零
remote_addr.sin_family=AF_INET; //設(shè)置為IP通信
remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服務(wù)器IP地址
remote_addr.sin_port=htons(8000); //服務(wù)器端口號
/*創(chuàng)建客戶端套接字--IPv4協(xié)議,面向連接通信,TCP協(xié)議*/
if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))0)
{
perror("socket");
return 1;
}
/*將套接字綁定到服務(wù)器的網(wǎng)絡(luò)地址上*/
if(connect(client_sockfd,(struct sockaddr *)remote_addr,sizeof(struct sockaddr))0)
{
perror("connect");
return 1;
}
printf("connected to server/n");
len=recv(client_sockfd,buf,BUFSIZ,0);//接收服務(wù)器端信息
buf[len]='/0';
printf("%s",buf); //打印服務(wù)器端信息
/*循環(huán)的發(fā)送接收信息并打印接收信息--recv返回接收到的字節(jié)數(shù),send返回發(fā)送的字節(jié)數(shù)*/
while(1)
{
printf("Enter string to send:");
scanf("%s",buf);
if(!strcmp(buf,"quit")
break;
len=send(client_sockfd,buf,strlen(buf),0);
len=recv(client_sockfd,buf,BUFSIZ,0);
buf[len]='/0';
printf("received:%s/n",buf);
}
close(client_sockfd);//關(guān)閉套接字
return 0;
}
#include stdlib.h
#include stdio.h
#include errno.h
#include string.h
#include sys/types.h
#include netinet/in.h
#include sys/wait.h
#include sys/socket.h
#define PORT 5000 // The port which is communicate with server
#define BACKLOG 10
#define LENGTH 512 // Buffer length
int main ()
{ int sockfd; // Socket file descriptor
int nsockfd; // New Socket file descriptor
int num;
int sin_size; // to store struct size
char sdbuf[LENGTH]; // Send buffer
struct sockaddr_in addr_local;
struct sockaddr_in addr_remote;
char sendstr[16]= {"123456789 abcde"};
/* Get the Socket file descriptor */
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
{
printf ("ERROR: Failed to obtain Socket Despcritor.\n");
return (0);
}
else
{
printf ("OK: Obtain Socket Despcritor sucessfully.\n");
}
/* Fill the local socket address struct */
addr_local.sin_family = AF_INET; // Protocol Family
addr_local.sin_port = htons(PORT); // Port number
addr_local.sin_addr.s_addr = INADDR_ANY; // AutoFill local address
bzero((addr_local.sin_zero), 8); // Flush the rest of struct
/* Blind a special Port */
if( bind(sockfd, (struct sockaddr*)addr_local, sizeof(struct sockaddr)) == -1 )
{
printf ("ERROR: Failed to bind Port %d.\n",PORT);
return (0);
}
else
{
printf("OK: Bind the Port %d sucessfully.\n",PORT);
}
/* Listen remote connect/calling */
if(listen(sockfd,BACKLOG) == -1)
{
printf ("ERROR: Failed to listen Port %d.\n", PORT);
return (0);
}
else
{
printf ("OK: Listening the Port %d sucessfully.\n", PORT);
}
while(1)
{
sin_size = sizeof(struct sockaddr_in);
/* Wait a connection, and obtain a new socket file despriptor for single connection */
if ((nsockfd = accept(sockfd, (struct sockaddr *)addr_remote, sin_size)) == -1)
{
printf ("ERROR: Obtain new Socket Despcritor error.\n");
continue;
}
else
{
printf ("OK: Server has got connect from %s.\n", inet_ntoa(addr_remote.sin_addr));
}
/* Child process */
if(!fork())
{
printf("You can enter string, and press 'exit' to end the connect.\n");
while(strcmp(sdbuf,"exit") != 0)
{
scanf("%s", sdbuf);
if((num = send(nsockfd, sdbuf, strlen(sdbuf), 0)) == -1)
{
printf("ERROR: Failed to sent string.\n");
close(nsockfd);
exit(1);
}
printf("OK: Sent %d bytes sucessful, please enter again.\n", num);
}
}
close(nsockfd);
while(waitpid(-1, NULL, WNOHANG) 0);
}
}
給你兩個簡單示例參考下,先運行服務(wù)端,再運行客服端,可以實現(xiàn)兩者之間的通信。
服務(wù)端:
#include WINSOCK2.H
#include iostream
using namespace std;
#pragma comment(lib,"ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
SOCKET listenfd = socket(AF_INET,SOCK_STREAM,0);
if (listenfd == INVALID_SOCKET)
{
cout"socket failed with err code="WSAGetLastError()endl;
return;
}
sockaddr_in servaddr;
memset(servaddr,0,sizeof(sockaddr_in));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5555);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
// servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int opt = 1;
int ret = setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,(const char*)opt,sizeof(opt));
if (ret == SOCKET_ERROR)
{
cout"setsockopt failed with err code="WSAGetLastError()endl;
return;
}
ret = bind(listenfd,(sockaddr*)servaddr,sizeof(servaddr));
if (ret == SOCKET_ERROR)
{
cout"bind failed with err code="WSAGetLastError()endl;
return;
}
ret = listen(listenfd,10);
if (ret == SOCKET_ERROR)
{
cout"listen failed with err code="WSAGetLastError()endl;
return;
}
sockaddr_in peeraddr;
int len = sizeof(sockaddr_in);
// while (1)
// {
SOCKET connSocket = accept(listenfd,(sockaddr*)peeraddr,len);
if (connSocket == INVALID_SOCKET)
{
cout"accept failed with err code="WSAGetLastError()endl;
return;
}
// 開辟一個線程
cout"peer ip=["inet_ntoa(peeraddr.sin_addr)"]"" port=["ntohs(peeraddr.sin_port)"]"endl;
send(connSocket,"welcome to by",strlen("welcome to by"),0);
char buf[1024];
while (1)
{
memset(buf,0,sizeof(buf));
recv(connSocket,buf,1024,0);
coutbufendl;
send(connSocket,buf,strlen(buf),0);
}
}
客戶端:
#include WINSOCK2.H
#include iostream
using namespace std;
#pragma comment(lib,"ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
SOCKET sock = socket(AF_INET,SOCK_STREAM,0);
if (sock == INVALID_SOCKET)
{
cout"socket failed with err code="WSAGetLastError()endl;
return;
}
sockaddr_in servaddr;
memset(servaddr,0,sizeof(sockaddr_in));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5555);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = connect(sock,(sockaddr*)servaddr,sizeof(servaddr));
if (ret == SOCKET_ERROR)
{
cout"connect failed with err code="WSAGetLastError()endl;
return;
}
char recvbuf[1024] = {0};
recv(sock,recvbuf,1024,0);
coutrecvbufendl;
char sendbuf[1024] = {0};
while (1)
{
memset(sendbuf,0,sizeof(sendbuf));
memset(recvbuf,0,sizeof(recvbuf));
cinsendbuf;
send(sock,sendbuf,strlen(sendbuf),0);
recv(sock,recvbuf,1024,0);
coutrecvbufendl;
}
}