//server.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#define PORT 4321
#define MAX_QUE_CONN_NM 5
#define MAXLEN 1024
#define RET_OK 1
#define RET_ERROR 0
int socket_listen()
{
int sockfd;
struct sockaddr_in server_sockaddr;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
return RET_ERROR;
}
bzero(&server_sockaddr, sizeof(server_sockaddr));
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr*)(&server_sockaddr), sizeof(struct sockaddr)) == -1)
{
return RET_ERROR;
}
if (listen(sockfd, MAX_QUE_CONN_NM) == -1)
{
return RET_ERROR;
}
return sockfd;
}
int server_socket_listen()
{
int sin_size;
int recvbytes;
int sockfd;
int client_fd;
char server_buf[MAXLEN];
int sendbytes;
struct sockaddr_in client_sockaddr;
sockfd = socket_listen();
if (sockfd == RET_ERROR)
{
return RET_ERROR;
}
while (1)
{
sin_size = sizeof(struct sockaddr_in);
if ((client_fd = accept(sockfd, (struct sockaddr*) & client_sockaddr, &sin_size)) == -1)
{
return RET_ERROR;
}
memset(server_buf, 0, sizeof(server_buf));
recvbytes = recv(client_fd, server_buf, MAXLEN, 0);
if (recvbytes < 0)
{
return RET_ERROR;
}
}
close(sockfd);
return RET_OK;
}
int main()
{
server_socket_listen();
return 0;
}
//client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT 4321
#define BUFFER_SIZE 1024
int main(int argc,char *argv[])
{
int sockfd;
int sendbytes;
char buf[BUFFER_SIZE];
struct hostent *host;
struct sockaddr_in server_addr;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
printf("socket created\n");
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("connect");
exit(1);
}
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s", "hello");
if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
{
perror("send");
exit(1);
}
memset(buf, 0, sizeof(buf));
recv(sockfd, buf, 1024, 0);
printf("recv:%s\n", buf);
close(sockfd);
return 0;
}
阻塞模式:常见的通信模型为多线程模型,服务端accept之后,对每个socket创建一个线程去recv。
逻辑上简单,适用于并发量小(客户端数目小),连续传输大数据量的情况下,比如文件服务器。还有就是客户端recv服务器消息的时候也经常用,因为客户端就一个socket,用阻塞模式不影响效率,而且编程逻辑上要简单的多。
非阻塞模式,常见的通信模型为select模型和IOCP模型。适用于高并发,数据量小的情况,比如聊天室。客户端多的情况下,如果采用阻塞模式,需要开很多线程,影响效率。另外,客户端一般不采用非阻塞模式。