扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
函数说明:socket()用来建立一个新的socket, 也就是向系统注册, 通知系统建立一通信端口. 参数domain 指定使用何种的地址类型, 完整的定义在/usr/include/bits/socket.h 内, 底下是常见的协议:
创新互联公司是一家专注于成都网站制作、成都网站设计与策划设计,岫岩网站建设哪家好?创新互联公司做网站,专注于网站建设10余年,网设计领域的专业建站公司;建站业务涵盖:岫岩等地区。岫岩做网站价格咨询:028-86922220
PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX 进程通信协议
PF_INET?AF_INET Ipv4 网络协议
PF_INET6/AF_INET6 Ipv6 网络协议
PF_IPX/AF_IPX IPX-Novell 协议
PF_NETLINK/AF_NETLINK 核心用户接口装置
PF_X25/AF_X25 ITU-T X. 25/ISO-8208 协议
PF_AX25/AF_AX25 业余无线AX. 25 协议
PF_ATMPVC/AF_ATMPVC 存取原始 ATM PVCs
PF_APPLETALK/AF_APPLETALK appletalk (DDP)协议
PF_PACKET/AF_PACKET 初级封包接口
参数 type 有下列几种数值:
1、SOCK_STREAM 提供双向连续且可信赖的数据流, 即TCP. 支持 OOB 机制, 在所有数据传送前必须使用connect()来建立连线状态.
2、SOCK_DGRAM 使用不连续不可信赖的数据包连接
3、SOCK_SEQPACKET 提供连续可信赖的数据包连接
4、SOCK_RAW 提供原始网络协议存取
5、SOCK_RDM 提供可信赖的数据包连接
6、SOCK_PACKET 提供和网络驱动程序直接通信. protocol 用来指定socket 所使用的传输协议编号, 通常此参考不用管它, 设为0 即可.
返回值:成功则返回socket 处理代码, 失败返回-1.
错误代码:
1、EPROTONOSUPPORT 参数domain 指定的类型不支持参数type 或protocol 指定的协议
2、ENFILE 核心内存不足, 无法建立新的socket 结构
3、EMFILE 进程文件表溢出, 无法再建立新的socket
4、EACCESS 权限不足, 无法建立type 或protocol 指定的协议
5、ENOBUFS/ENOMEM 内存不足
6、EINVAL 参数domain/type/protocol 不合法
谁能告诉我accept()函数返回一个新的套接字,所谓新套接字就是说这个是新产生的套接字,并不是你用来accept的那个监听的套接字。
accept()函数用于一个套接口接受一个连接。accept()是c语言中网络编程的重要的函数,windows系统在#includewinsock.h ,而linux系统在#include sys/socket.h中。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:套接口描述字,该套接口在listen()后监听连接。
addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数。
实例:
#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 ;
}
如果你要编写的是一个服务程序,那么先调用socket()创建一个套接字,然后调用bind()绑定ip地址和端口,再然后启动一个死循环,循环中调用accept()接受连接,对于每个接受的连接,可以起线程进行处理,在线程中调用send()、recv()发送和接收数据。
如果你要编写的是一个客户端程序,那么就简单多了,先调用socket()创建一个套接字,然后调用connect()连接服务器,之后就是调用send()、recv()发送和接收数据了。
#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;//服务器端套接字
int client_sockfd;//客户端套接字
int len;
struct sockaddr_in my_addr; //服务器网络地址结构体
struct sockaddr_in remote_addr; //客户端网络地址结构体
int sin_size;
char buf[BUFSIZ]; //数据传送的缓冲区
memset(my_addr,0,sizeof(my_addr)); //数据初始化--清零
my_addr.sin_family=AF_INET; //设置为IP通信
my_addr.sin_addr.s_addr=INADDR_ANY;//服务器IP地址--允许连接到所有本地地址上
my_addr.sin_port=htons(8000); //服务器端口号
/*创建服务器端套接字--IPv4协议,面向连接通信,TCP协议*/
if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))0)
{
perror("socket");
return 1;
}
/*将套接字绑定到服务器的网络地址上*/
if (bind(server_sockfd,(struct sockaddr *)my_addr,sizeof(struct sockaddr))0)
{
perror("bind");
return 1;
}
/*监听连接请求--监听队列长度为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);//发送欢迎信息
/*接收客户端的数据并将其发送给客户端--recv返回接收到的字节数,send返回发送的字节数*/
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; //服务器端网络地址结构体
char buf[BUFSIZ]; //数据传送的缓冲区
memset(remote_addr,0,sizeof(remote_addr)); //数据初始化--清零
remote_addr.sin_family=AF_INET; //设置为IP通信
remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器IP地址
remote_addr.sin_port=htons(8000); //服务器端口号
/*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/
if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))0)
{
perror("socket");
return 1;
}
/*将套接字绑定到服务器的网络地址上*/
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);//接收服务器端信息
buf[len]='/0';
printf("%s",buf); //打印服务器端信息
/*循环的发送接收信息并打印接收信息--recv返回接收到的字节数,send返回发送的字节数*/
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);//关闭套接字
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);
}
}
给你两个简单示例参考下,先运行服务端,再运行客服端,可以实现两者之间的通信。
服务端:
#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;
}
}
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流