Linux TCP Socket实现进程间通信
Linux Socket由内核实现,全双工方式,单个客户端进程通过多条连接连上服务端后,并发发送请求并接收响应,最后关闭连接。
TCP是协议无实体,Socket是具体实现。
服务端
初始化Socket->绑定地址和端口->监听端口->accept阻塞等待客户端连接->处理请求并响应
客户端
初始化Socket->连接服务端->发送请求->读取数据->关闭连接
common.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 3000
#define MAX_CHARS 1000
#define MAX_CONNECTIONS 5
struct message {
char name[10];
int type;
};
client.c
#include "common.h"
int main(int argc, char **argv)
{
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1)
{
printf("create socket error: %s\n", strerror(errno));
exit(1);
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
if (connect(socket_fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
{
printf("connect error: %s\n", strerror(errno));
exit(1);
}
// 从终端读取字符串并发送
// char msg[MAX_CHARS];
// printf("send:\n");
// fgets(msg, MAX_CHARS, stdin);
// if (send(socket_fd, msg, strlen(msg), 0) == -1)
// {
// printf("send error: %s\n", strerror(errno));
// exit(1);
// }
char buff[MAX_CHARS];
struct message msg;
strcpy(msg.name, "test");
msg.type = 100;
memcpy(buff, &msg, sizeof(msg));
if (send(socket_fd, buff, sizeof(buff), 0) == -1)
{
printf("send error: %s\n", strerror(errno));
exit(1);
}
char buf[MAX_CHARS];
int n;
n = recv(socket_fd, buf, MAX_CHARS, 0);
if (n == -1)
{
perror("receive error");
exit(1);
}
buf[n] = '\0';
printf("receive: %s", buf);
close(socket_fd);
exit(0);
}
server.c
#include "common.h"
int main(int argc, char **argv)
{
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1)
{
printf("create socket error: %s\n", strerror(errno));
exit(1);
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
// INADDR_ANY表示本机地址
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
if (bind(socket_fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
{
printf("bind socket error: %s\n", strerror(errno));
exit(1);
}
if (listen(socket_fd, MAX_CONNECTIONS) == -1)
{
printf("listen socket error: %s\n", strerror(errno));
exit(1);
}
printf("handle client request\n");
while (1)
{
int connect_fd = accept(socket_fd, (struct sockaddr *)NULL, NULL);
if (connect_fd == -1)
{
printf("accept socket error: %s", strerror(errno));
continue;
}
char buff[MAX_CHARS];
int n = recv(connect_fd, buff, sizeof(buff), 0);
struct message *msg = (struct message *)buff;
printf("%s %d\n", msg->name, msg->type);
// int n;
// char buff[1000];
// n = recv(connect_fd, buff, MAX_CHARS, 0);
// 末尾设置字符数组结束标志
// buff[n] = '\0';
// printf("receive: %s", buff);
// 创建子进程来处理请求
if (!fork())
{
char resp[100] = "handle complete\n";
if (send(connect_fd, resp, strlen(resp), 0) == -1)
perror("send error");
close(connect_fd);
exit(0);
}
close(connect_fd);
}
close(socket_fd);
exit(0);
}