client.c
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
//1 建立通信套接字
int fd = socket(AF_INET,SOCK_STREAM,0);
if(fd == -1)
{
printf("fail to socket");
exit(1);
}
//2 连接服务器
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr =htonl(INADDR_ANY);
int ret = connect(fd,(struct sockaddr*)&addr,sizeof(addr));
if(ret == -1)
{
printf("fail to connect");
exit(1);
}
//3 通信
//int number = 1;
while(1)
{
//发送数据
char buff[1024];
//sprintf(buff,"你好,服务器,第%d次和你通信",number++);
//gets(buff);
printf("pls say sth to server:\n");
fgets(buff,sizeof(buff),stdin);
send(fd,buff,strlen(buff)+1,0);
//接收数据
memset(buff,0,1024);
int len = recv(fd,buff,sizeof(buff),0);
if(len > 0)
{
printf("服务器 :%s\n",buff);
}else if(len == 0)
{
printf("和服务器的连接断开\n");
break;
}else
{
perror("fail to read");
break;
}
sleep(1);
}
//4 关闭通信套接字
close(fd);
}
server.c
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
//1 创建监听套接字
int fd = socket(AF_INET,SOCK_STREAM,0);
if(fd == -1)
{
perror("fail to socket");
exit(1);
}
//2 绑定我们本地的IP地址和端口号
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
if(ret == -1)
{
perror("fail to bind");
exit(1);
}
//3 设置监听
ret = listen(fd,128);
if(ret == -1)
{
perror("fail to listen");
exit(1);
}
//4 阻塞等待,连接的到达,连接成功后返回通信用的套接字
struct sockaddr_in caddr;
int caddrlen = sizeof(caddr);
int fdc = accept(fd,(struct sockaddr *)&caddr,&caddrlen);
if(fdc == -1)
{
perror("fail to accept");
exit(1);
}
//5 开始通信
while(1)
{
char buff[1024];
memset(buff,0,sizeof(buff));
int len = read(fdc,buff,1024);
char ip[30] = {0};
if(len > 0)
{
printf("客户端 %s:%d : %s \n",
inet_ntop(AF_INET,&caddr.sin_addr,ip,sizeof(ip)),
ntohs(caddr.sin_port),
buff);
write(fdc,buff,len);
}
if(len = 0)
{
printf("连接已断开\n");
break;
}
if(len < 0)
{
perror("fail to read");
break;
}
}
//6 关闭套接字
close(fd);
close(fdc);
}
运行结果:
如果server.c改一下
那么运行结果变成
多进程实现TCP服务器开发
client.c跟上面的一样
server_fort.c
#include
#include
#include
#include
#include
#include
void handler(int sig)
{
wait(NULL);
}
int main(int argc, char *argv[])
{
//1 创建监听套接字
int fd = socket(AF_INET,SOCK_STREAM,0);
if(fd == -1)
{
perror("fail to socket");
exit(1);
}
//设置套接字,可以重复使用本机地址,和端口复用
int on = 1;
if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
{
perror("fail to setsockopt");
exit(1);
}
//2 绑定我们本地的IP地址和端口号
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
if(ret == -1)
{
perror("fail to bind");
exit(1);
}
//3 设置监听
ret = listen(fd,128);
if(ret == -1)
{
perror("fail to listen");
exit(1);
}
signal(SIGCHLD,handler);
while(1)
{
//4 阻塞等待,连接的到达,连接成功后返回通信用的套接字
struct sockaddr_in caddr;
int caddrlen = sizeof(caddr);
int fdc = accept(fd,(struct sockaddr *)&caddr,&caddrlen);
if(fdc == -1)
{
perror("fail to accept");
exit(1);
}
pid_t pid = fork();
if(pid < 0)
{
perror("fail to pid");
exit(1);
}
if(pid == 0)
{
//5 开始通信
while(1)
{
char buff[1024];
memset(buff,0,sizeof(buff));
int len = read(fdc,buff,1024);
char ip[30] = {0};
if(len > 0)
{
printf("客户端 %s:%d : %s \n",
inet_ntop(AF_INET,&caddr.sin_addr,ip,sizeof(ip)),
ntohs(caddr.sin_port),
buff);
write(fdc,buff,len);
}
if(len = 0)
{
printf("连接已断开\n");
break;
}
if(len < 0)
{
perror("fail to read");
break;
}
}
close(fdc);
}
}
//6 关闭套接字
close(fd);
}
运行结果:
多线程实现TCP服务器并发
client.c跟上面的一样
server_thread.c
#include
#include
#include
#include
#include
#include
struct Sss{
struct sockaddr_in caddr;
int fdc;
};
void *thread_fun(void *arg)
{
struct Sss sss =*(struct Sss *)arg;
int fdc = sss.fdc;
struct sockaddr_in caddr = sss.caddr;
//5 开始通信
while(1)
{
char buff[1024];
memset(buff,0,sizeof(buff));
int len = read(fdc,buff,1024);
char ip[30] = {0};
if(len > 0)
{
printf("客户端 %s:%d : %s \n",
inet_ntop(AF_INET,&caddr.sin_addr,ip,sizeof(ip)),
ntohs(caddr.sin_port),
buff);
write(fdc,buff,len);
}
if(len = 0)
{
printf("连接已断开\n");
break;
}
if(len < 0)
{
perror("fail to read");
break;
}
}
close(fdc);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
//1 创建监听套接字
int fd = socket(AF_INET,SOCK_STREAM,0);
if(fd == -1)
{
perror("fail to socket");
exit(1);
}
//设置套接字,可以重复使用本机地址,和端口复用
int on = 1;
if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
{
perror("fail to setsockopt");
exit(1);
}
//2 绑定我们本地的IP地址和端口号
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
if(ret == -1)
{
perror("fail to bind");
exit(1);
}
//3 设置监听
ret = listen(fd,128);
if(ret == -1)
{
perror("fail to listen");
exit(1);
}
while(1)
{
//4 阻塞等待,连接的到达,连接成功后返回通信用的套接字
struct sockaddr_in caddr;
int caddrlen = sizeof(caddr);
int fdc = accept(fd,(struct sockaddr *)&caddr,&caddrlen);
if(fdc == -1)
{
perror("fail to accept");
exit(1);
}
struct Sss sss;
sss.caddr = caddr;
sss.fdc = fdc;
pthread_t thread;
// pthread create(&thread,NULL,thread_fun,&fdc);
pthread_create(&thread,NULL,thread_fun,&sss);
pthread_detach(thread);
}
//6 关闭套接字
close(fd);
//close(fdc);
}
编译命令
gcc server_thread.c -o server_thread -lpthread
然后
./server_thread
运行结果:
以上代码跟着b站博主敲的
地址https://www.bilibili.com/video/BV1W64y1k75t
线程池实现TCP服务器并发没弄
推荐并发网络通信-套接字通信(C/C++ 多线程)
地址https://www.bilibili.com/video/BV1F64y1U7A2