/*******************************************************************************************
例程说明:创建一个TCP/IP服务器,接收客户端发来的消息
1.创建socket
2.绑定IP地址和端口号到socket
3.设置连接最大数量
4.accept()等待客户端连接
5.接收数据
6.接收到数据后关闭连接
*******************************************************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <errno.h>
#define portnumber 3333
/*******************************************************************************************
Function:
Description:
The functionality of socket()
int socket(int domain, int type, int protocol);
@domain - selects the protocol family
val:
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX - Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK Appletalk ddp(7)
AF_PACKET Low level packet interface packet(7)
@type - specifies the communication semantics
val:
SOCK_STREAM sequenced, reliable, two-way, connection-based byte streams.
SOCK_DGRAM connectionless, unreliable messages
SOCK_SEQPACKET sequenced, reliable, two-way connection-based data
SOCK_RAW raw network protocol access.
SOCK_RDM reliable datagram layer that does not guar‐antee ordering.
SOCK_PACKET Obsolete and should not be used in new programs;
@protocol - specify the index of particular protocol,which will take place of domain.
Normally it can be specified as 0.
*******************************************************************************************/
int main(int args,char *argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr; // IP data structure
struct sockaddr_in client_addr;
int sin_size;
int nbytes;
char buffer[1024]; // buffer for receiving
// 服务器端开始建立sockfd描述符
if( (sockfd=socket(AF_INET,SOCK_STREAM,0))==-1 ) // AF_INET - IPV4,SOCK_STREAN - byte stream,protocol - narmal
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
}
// 服务器端填充 sockaddr 结构体
bzero(&server_addr,sizeof(struct sockaddr_in)); // 数据清0
server_addr.sin_family = AF_INET; // IP协议
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 响应本机所有网卡收到的数据,将IP地址转换成网络IP格式(端转换)
server_addr.sin_port = htons(portnumber); // 转换端口号
// 绑定IP地址和端口到socket
if( bind(sockfd,(struct sockaddr *)(&server_addr), sizeof(struct sockaddr))==-1 )
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
}
// 设置允许连接的最大数目
if( listen(sockfd,5)==-1 )
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
while(1)
{
// 服务器阻塞直到客户连接到服务器
printf("Wait client to connect!\n");
sin_size = sizeof(struct sockaddr_in);
if( (new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1 )
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
exit(1);
}
fprintf(stderr,"Server get connection form %s\n",inet_ntoa(client_addr.sin_addr));
if( (nbytes=read(new_fd,buffer,1024))==-1 )
{
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
}
buffer[nbytes] = '\0';
printf("Server received a data from client: %s\n",buffer);
// 关闭连接
close(new_fd);
// 循环下一个
}
return(0);
}