//warning gcc compile error : ocket operation on non-socket
//产生原因,创建、绑定、接受绑定错误判断时,忘记加“()”了
// if( ( sockfd = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) 正确
// if( sockfd = socket ( AF_INET, SOCK_STREAM, 0 ) < 0 ) 错误
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#define errmes(message) do{perror(message);exit(1);}while(0)
#define N 128
int main(int argc, const char *argv[])
{
int sockfd, acceptfd;
struct sockaddr_in serveraddr, clientaddr;
socklen_t clientlen = sizeof(clientaddr);
char buf[N]; //char buf[N] = {};这样定义的数组里是空的。
//1.创建套接字
//AF_INET:IPv4的模式 SOCK_STREAM:流式套接字(可靠,可连接) 0:可读可写(当第三个参数为0时,
//会自动选择第二个参数类型对应的默认协议)
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
errmes("fail to socket");
}
//填充网络信息结构体
serveraddr.sin_family = AF_INET; //sin_family:地址家族,对应socket第一个参数
serveraddr.sin_addr.s_addr = inet_addr(argv[1]); //ip地址 inet_addr()将点分十进制字节序数据
//转换成网络字节序数据
serveraddr.sin_port = htons(atoi(argv[2])); //端口号 htons()将整型变量从主机字节顺序转变成网络字节顺序
//h:host:主机 n:network:网络
if((bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0)
{
errmes("fail to bind");
}
if(listen(sockfd, 10) < 0)
{
errmes("fail to listen");
}
if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientlen)) < 0)
//只有在接受客户端的连接请求时,才需要将结构体长度取地址
{
errmes("fail to accept");
}
bzero(buf, 0); //见字符串buf前n(此处等于0)个字节清零
while(1)
{
recv(acceptfd, buf, N, 0); //将accept以阻塞方式(0)接收到的N个大小数据放入到buf里面
printf("client said: %s\n",buf);
if(strncmp(buf, "quit", 4) == 0) //将buf里的数据和quit进行比较,相等返回0
{
printf("server leave..");
break;
}
}
printf("%s\n",buf);
close(sockfd); //最后要将两个文件描述符关闭
close(acceptfd);
return 0;
}