Linux C实现简单,多进程,多线程服务器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux C实现简单,多进程,多线程服务器相关的知识,希望对你有一定的参考价值。
简单服务器
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main(){
// 创建服务端fd
int listenfd = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
if(listenfd < 0){
printf("socket error");
return -1;
}
// 创建IP地址
struct sockaddr_in svraddr;/*声明一个变量,类型为协议地址类型*/
svraddr.sin_family = AF_INET;/*使用IPv4协议*/
svraddr.sin_port = htons(8887);/*监听8887端口*/
svraddr.sin_addr.s_addr = htonl(INADDR_ANY);/*绑定本机IP,使用宏定义绑定*/
// 服务端fd和ip地址绑定
if(bind(listenfd ,(struct sockaddr *)&svraddr,sizeof(svraddr)) < 0){
printf("bind error");
return -1;
}
// 上面创建和客户端一样,closed状态,当调用listen后从closed状态转listen
if(listen(listenfd, 20) < 0){
printf("listen error");
return -1;
}
// 下面是客户端socket
struct sockaddr_in cliaddr;/*只是声明,并没有赋值*/
memset(&cliaddr, 0, sizeof(cliaddr));
socklen_t ret = sizeof(cliaddr);
// accept会阻塞进程
// 客户端生成的fd,通过给客户端fd写入内容就会发送到客户端
int sockfd= accept(listenfd, (struct sockaddr*)&cliaddr, &ret);
if(sockfd < 0){
printf("appect error");
return -1;
}
char str[] = "Hello World";
write(sockfd , str, sizeof(str));
close(sockfd);
close(listenfd);
}
客户端代码
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main()
{
int sockfd= socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
if(sockfd== -1){
printf("socket error");
return -1;
}
struct sockaddr_in svraddr;
svraddr.sin_family = AF_INET;/*使用IPv4协议*/
svraddr.sin_port = htons(8887);/*需要连接的远程服务器端口*/
svraddr.sin_addr.s_addr = inet_addr("127.0.0.1");/*需要连接的远程服务器IP*/
if(connect(sockfd, (struct sockaddr *)&svraddr, sizeof(servaddr)) < 0){
printf("connect error");
return -1;
}
char str[64];
read(sockfd, str, 64);
printf(str);
close(sockfd);
}
多进程服务器
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
void doit(int sockfd);
int main()
{
int listenfd= socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
pid_t pid;
if(listenfd < 0){
printf("socket error");
return -1;
}
struct sockaddr_in svraddr;/*声明一个变量,类型为协议地址类型*/
svraddr.sin_family = AF_INET;/*使用IPv4协议*/
svraddr.sin_port = htons(8887);/*监听8887端口*/
svraddr.sin_addr.s_addr = htonl(INADDR_ANY);/*绑定本机IP,使用宏定义绑定*/
if(bind(listenfd,(struct sockaddr *)&svraddr,sizeof(svraddr)) < 0){
printf("bind error");
return -1;
}
if(listen(listenfd, 20) < 0){
printf("listen error");
return -1;
}
for( ; ; ){ /*while(1){} */
struct sockaddr_in cliaddr;/*只是声明,并没有赋值*/
socklen_t cliaddr_size = sizeof(cliaddr);
int sockfd= accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddr_size );
if(sockfd < 0){
printf("appect error");
return -1;
}
if( (pid = fork()) == 0 ){
close(listenfd);/*子进程不需要监听,关闭*/
doit(sockfd);/*针对已连接的客户端套接字进行读写*/
close(sockfd);/*处理完毕,关闭客户端连接*/
exit(0);/*自觉退出*/
}
close(sockfd);
/*close(listenfd);*/
}
}
void doit(int sockfd){
char str[] = "Hello World";
sleep(3);//3秒之后再向客户端发送数据
write(sockfd, str, sizeof(str));
}
多线程服务
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#define IP "192.168.102.175"
#define PORT 7000
void print_err(char *str, int line, int err_no) {
printf("%d, %s :%s\\n",line,str,strerror(err_no));
_exit(-1);
}
/*子线程中先接收从客户端发来的消息,再发送一个消息给客户端*/
void *receive(void *pth_arg) {
int ret = 0;
long cfd = (long)pth_arg;
char buf[100] = {0};
while(1) {
bzero(&buf, sizeof(buf));
ret = recv(cfd, &buf, sizeof(buf),0);
if (-1 == ret) {
print_err("recv failed",__LINE__,errno);
}
else if (ret > 0)
printf("recv from client %s \\n",buf);
ret = send(cfd,"recv ok\\n", sizeof("recv ok\\n"), 0);
if (-1 == ret) print_err("send failed", __LINE__, errno);
}
}
int main()
{
int skfd = -1, ret = -1;
skfd = socket(AF_INET, SOCK_STREAM, 0);
if ( -1 == skfd) {
print_err("socket failed",__LINE__,errno);
}
struct sockaddr_in addr;
addr.sin_family = AF_INET; //设置tcp协议族
addr.sin_port = htons(PORT); //设置端口号
addr.sin_addr.s_addr = inet_addr(IP); //设置ip地址
ret = bind(skfd, (struct sockaddr*)&addr, sizeof(addr));
if ( -1 == ret) {
print_err("bind failed",__LINE__,errno);
}
ret = listen(skfd, 3);
if ( -1 == ret ) {
print_err("listen failed", __LINE__, errno);
}
//使用accept阻塞形式得监听客户端的发来的连接,并返回通信描述符
long cfd = -1;
pthread_t id;
while (1) {
struct sockaddr_in caddr = {0};
int csize = sizeof(caddr);
cfd = accept(skfd, (struct sockaddr*)&caddr, &csize);
if (-1 == cfd) {
print_err("accept failed", __LINE__, errno);
}
//建立连接后打印一下客户端的ip和端口号
printf("cport = %d, caddr = %s\\n", ntohs(caddr.sin_port),inet_ntoa(caddr.sin_addr));
//使用accept返回到描述符,创建子线程进行数据传输
int ret = pthread_create(&id,NULL,receive,(void*)cfd);
if(-1 == ret) print_err("accept failed", __LINE__, errno);
}
return 0;
}
以上是关于Linux C实现简单,多进程,多线程服务器的主要内容,如果未能解决你的问题,请参考以下文章