目录
TCP协议Linux多进程服务器代码模板:
TCP协议Linux多线程服务器代码模板:
客户端代码模板:
#include
#include
#include
#include
#include
#include
#include
#include
// 信号捕捉函数
void recycleChild(int num)
{
// 资源回收
while(1)
{
int ret = waitpid(-1, NULL, WNOHANG);
if(ret == -1)
{
printf("所有的子进程回收完毕!!!\n");
break;
}
else if(ret == 0)
{
printf("剩下的子进程都还活着!!!\n");
break;
}
else
{
printf("child die, pid = %d\n", ret);
}
}
}
int main()
{
// 1. 创建用于监听的套接字
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
perror("socket");
exit(0);
}
// 2. 绑定
struct sockaddr_in addr;
addr.sin_family = AF_INET; // ipv4
addr.sin_port = htons(8989); // 字节序应该是网络字节序
//inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_addr.s_addr = INADDR_ANY; // == 0, 获取IP的操作交给了内核
int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
if(ret == -1)
{
perror("bind");
exit(0);
}
// 3.设置监听
ret = listen(fd, 100);
if(ret == -1)
{
perror("listen");
exit(0);
}
// 注册新号捕捉
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = recycleChild;
sigemptyset(&act.sa_mask);
sigaction(SIGCHLD, &act, NULL);
while(1)
{
// 4. 等待, 接受连接请求
struct sockaddr_in addrCli;
int len = sizeof(addrCli);
printf("正在焦急等待客户端的连接...\n");
int connfd = accept(fd, (struct sockaddr*)&addrCli, &len);
if(connfd == -1)
{
if(errno == EINTR)
{
continue;
}
perror("accept");
exit(0);
}
// 成功和客户端建立了连接
// 创建子进程
pid_t pid = fork();
if(pid == 0)
{
int num = 0;
while(1)
{
// 读数据
char recvBuf[1024];
// 如果客户端没有发送数据, 默认阻塞
int ret = read(connfd, recvBuf, sizeof(recvBuf));
if(ret == -1)
{
perror("read");
break;
}
else if(ret == 0)
{
printf("客户端已经断开了连接...\n");
break;
}
else
{
// 打印客户端地址信息
char ip[32];
inet_ntop(AF_INET, &addrCli.sin_addr.s_addr, ip, sizeof(ip));
printf("client IP: %s, Port: %d\n", ip, ntohs(addrCli.sin_port));
printf("客户端说: %s\n", recvBuf);
// 写数据
sprintf(recvBuf, "你好, 客户端 - %d\n", num++);
write(connfd, recvBuf, strlen(recvBuf)+1);
}
}
close(connfd); // 通信
// 退出当前子进程
exit(0);
}
}
// 释放资源
close(fd); // 监听
return 0;
}
编译的时候记得加动态库pthread库:gcc pthread_test.c -o test.out -l pthread
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct SockInfo
{
int fd; // 通信
pthread_t tid; // 线程ID
struct sockaddr_in addr; // 地址信息
};
struct SockInfo infos[128];
void* working(void* arg)
{
int num = 0;
while (1)
{
struct SockInfo* ptr = (struct SockInfo*)arg;
//通讯
char recvBuf[1024];
//如果客户端没有发数据,默认阻塞
int ret = read(ptr->fd, recvBuf, sizeof(recvBuf));
if (ret == -1)
{
perror("read");
break;
}
else if (ret == 0)
{
printf("客户端已经断开了连接...\n");
ptr->fd = -1;
break;
}
else
{
char ipbuf[64];
inet_ntop(AF_INET, &ptr->addr.sin_addr.s_addr, ipbuf, sizeof(ipbuf));
printf("current client: %s, port:%d\n", ipbuf, ntohs(ptr->addr.sin_port));
printf("客户端说: %s\n", recvBuf);
// 写数据
sprintf(recvBuf, "你好, 客户端 - %d\n", num++);
write(ptr->fd, recvBuf, strlen(recvBuf)+1);
}
}
}
int main()
{
// 1. 创建用于监听的套接字
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
perror("socket");
exit(0);
}
// 2. 绑定
struct sockaddr_in addr;
addr.sin_family = AF_INET; // ipv4
addr.sin_port = htons(8989); // 字节序应该是网络字节序
//inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_addr.s_addr = INADDR_ANY; // == 0, 获取IP的操作交给了内核
int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
if(ret == -1)
{
perror("bind");
exit(0);
}
// 3.设置监听
ret = listen(fd, 100);
if(ret == -1)
{
perror("listen");
exit(0);
}
// 4. 等待, 接受连接请求
int len = sizeof(struct sockaddr);
// 数据初始化
int max = sizeof(infos) / sizeof(infos[0]);
for(int i=0; iaddr, &len);
printf("parent thread, connfd: %d\n", connfd);
if(connfd == -1)
{
perror("accept");
exit(0);
}
pinfo->fd = connfd;
pthread_create(&pinfo->tid, NULL, working, pinfo);
pthread_detach(pinfo->tid);
}
// 释放资源
close(fd); // 监听
return 0;
}
#include
#include
#include
#include
#include
int main()
{
// 1. 创建用于通信的套接字
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
perror("socket");
exit(0);
}
// 2. 连接服务器
struct sockaddr_in addr;
addr.sin_family = AF_INET; // ipv4
addr.sin_port = htons(8989); // 服务器监听的端口, 字节序应该是网络字节序
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
if(ret == -1)
{
perror("connect");
exit(0);
}
int i = 0;
// 通信
while(1)
{
// 读数据
char recvBuf[1024];
// 写数据
sprintf(recvBuf, "data: %d\n", i++);
write(fd, recvBuf, strlen(recvBuf)+1);
// 如果客户端没有发送数据, 默认阻塞
read(fd, recvBuf, sizeof(recvBuf));
printf("recv buf: %s\n", recvBuf);
sleep(1);
}
// 释放资源
close(fd);
return 0;
}