最近在看redis的事件驱动相关的源码,使用epoll来做IO事件的注册和触发,所以先重新学习整理下socket编程。
打算总共写三篇文章
- 简单socket示例
- epoll socket
- redis的事件驱动
在实现之前先整理下接下来会用到的socket的接口 通过man查看各个接口的功能和参数
int socket(int domain, int type, int protocol);
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
int listen(int socket, int backlog);
int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
int connect(int socket, const struct sockaddr *address, socklen_t address_len);
ssize_t send(int socket, const void *buffer, size_t length, int flags);
ssize_t recv(int socket, void *buffer, size_t length, int flags);
int close(int fildes);
接下来做一个最简单的1对1的server和client的socket通信的模型示例
- server 启动等待连接
- client发起连接,
- serverd端响应并发送消息,
- client端接受并显示
//server
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
int socket_fd = 0;
//create socket
if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("create socket failed %s:%d\n", strerror(errno), errno);
exit(1);
}
//init sockaddr
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(2323);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//bind
if(bind(socket_fd, &server_addr, sizeof(server_addr)) < 0) {
printf("bind failed %s:%d\n", strerror(errno), errno);
exit(1);
}
//listen
if(listen(socket_fd, 10) < 0) {
printf("listen failed %s:%d\n", strerror(errno), errno);
exit(1);
}
printf("The server is now ready to accept connections\n");
for(;;)
{
struct sockaddr_in client_addr;
int client_size = sizeof(client_addr);
//accpet
int client_fd = accept(socket_fd, &client_addr, &client_size);
printf("new client accept %d\n", client_fd);
//send msg
char *msg = "connect success\n";
send(client_fd, msg, strlen(msg) + sizeof(char), 0);
close(client_fd);
}
}
//client
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
int socket_fd = 0;
//create socket
if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("create socket failed %s:%d\n", strerror(errno), errno);
exit(1);
}
//init sockaddr
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(2323);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(socket_fd, &server_addr, sizeof(server_addr)) < 0){
printf("connect failed %s:%d\n", strerror(errno), errno);
exit(1);
}
char recv_buf[100];
int left_len = 0;
recv(socket_fd, recv_buf, 100, 0);
printf("%s\n", recv_buf);
}