#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
int main()
{
char buf[1024];//用于存放数据的buf
int sockfd;//文件描述符
struct sockaddr_in cliaddr;//socket变量
socklen_t len;//strcut sockaddr_in变量的长度
bzero(buf, sizeof(buf));//清空buf
bzero(&cliaddr, sizeof(cliaddr));//清空cliaddr变量
sockfd = socket(AF_INET, SOCK_STREAM, 0);//采用TCP协议,返回值是文件描述符
if (sockfd == -1)//返回值为-1代表出错,成功时返回一个很小的整数
{
printf("socket error\n");
return EXIT_FAILURE;
}
len = sizeof(cliaddr);
cliaddr.sin_family = AF_INET;
//通过ip地址和端口号可以确定一个连接到一台主机的一个进程
cliaddr.sin_port = htons(8080);//填写端口号
//“192.168.164.136”是服务器的ip地址
if (inet_pton(AF_INET, "192.168.164.136", &cliaddr.sin_addr) <= 0)//填写服务器的IP地址
{
printf("inet_pton error\n");
return EXIT_FAILURE;
}
//通过connect函数建立连接
if (connect(sockfd, (struct sockaddr*)&cliaddr, len) == -1)
{
printf("connect error\n");
return EXIT_FAILURE;
}
//通标注输入读取数据
read(STDIN_FILENO, buf, sizeof(buf));
//通过文件描述符把数据发送给服务器进程
write(sockfd, buf, strlen(buf));
//清空buf
bzero(buf, sizeof(buf));
//通过文件描述符从服务器读取数据
read(sockfd, buf, sizeof(buf));
//把从服务器读取的数据写到标准输出
write(STDOUT_FILENO, buf, strlen(buf));
//关闭文件描述符
close(sockfd);
printf("Hello World\n");
return EXIT_SUCCESS;
}
/* 以上是client端代码 client.c */
/* include signal */
#include <signal.h>
#include <stdio.h>
void *
_signal(int signo, void *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM)
{
act.sa_flags |= SA_INTERRUPT;
}
else
{
act.sa_flags |= SA_RESTART;
}
if (sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);
return(oact.sa_handler);
}
/* end signal */
void * Signal(int signo, void *func)
{
void *sigfunc;
if ( (sigfunc = _signal(signo, func)) == SIG_ERR)
printf("signal error\n");
return(sigfunc);
}
/* 这个是信号处理函数,signal.c */
#include "signal.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
void sig_chld(int signo)
{
pid_t pid;
int stat;
while ((pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);
return ;
}
int main()
{
int i;
struct sockaddr_in servaddr;//服务器的socket变量
socklen_t len;//struct sockaddr_in 变量的长度
int sockfd;//服务器端的文件描述符
pid_t pid;//进程号的类型定义
Signal(SIGCHLD, sig_chld);//捕获信号函数,
//因为是fork一个子进程为client发送来的数据服务,所以通过信号来判断子进程是否服务结束
//通过信号来判断client是否已经断开连接,为client服务结束
sockfd = socket(AF_INET, SOCK_STREAM, 0);//采用TCP协议,返回值是文件描述符
if (sockfd == -1)
{
printf("socket error\n");
return EXIT_FAILURE;
}
len = sizeof(servaddr);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY代表服务器进程可以接受任何一个端口号
servaddr.sin_port = htons(8080);
//一个服务器进程需要绑定一个众所周知的地址或端口以等待客户来连接
if (bind(sockfd, (struct sockaddr*)&servaddr, len) == -1)
{
printf("bind error\n");
return EXIT_FAILURE;
}
//通过listen函数来监听有多少个client来连接,第2个参数代表最多可以有10个client来连接
if (listen(sockfd, 10) == -1)
{
printf("listen error\n");
return EXIT_FAILURE;
}
for (i = 0; i < 5; i++)
{
struct sockaddr_in client;
socklen_t len;
int clientfd;//client的文件描述符
char buf[1024];
bzero(buf, sizeof(buf));
bzero(&client, sizeof(client));
len = sizeof(client);
//.accept阻塞监听客户端链接请求 ----3次握手成功
clientfd = accept(sockfd, (struct sockaddr*)&client, &len);
if (clientfd == -1)
{
printf("acept error\n");
return EXIT_FAILURE;
}
pid = fork();//fork一个子进程为client进行服务
if (pid == 0)
{
close(sockfd);//关闭父进程的文件描述符
read(clientfd, buf, sizeof(buf));//读取client发送过来的数据
printf("%s\n", buf);//打印数据
bzero(buf, sizeof(buf));//清空buf
read(STDIN_FILENO, buf, sizeof(buf));//从标准输入 读取数据到buf
write(clientfd, buf, strlen(buf));//把数据写给client
close(clientfd);//关闭文件描述符
}
else if (pid > 0)
{
close(clientfd);//关闭clientfd描述符,避免浪费资源
}
else
{
printf("fork error\n");
return EXIT_FAILURE;
}
}
close(sockfd);
printf("Hello World\n");
return EXIT_SUCCESS;
}
/* 这个是server端进程 为server.c ,这个文件和signal.c一起工作 */