一个服务器和一个客户端可以很轻松的去写进行搭建连接的程序 但是客户端不止一个的同时就需要你去想一想
如何构思设置了 下面是自己利用进程知识写的两段代码 :
服务器代码段:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#define SERV_PORT 9000
#define BUFF_SIZE 1024
void handle_child(int sig)
{
int status ;
pid_t pid ;
while((pid = waitpid(-1,&status,WNOHANG))>0) ;
printf("a child has dead\n") ;
}
int server_request(int cfd)
{
int readSize, writeSize;
char buff[BUFF_SIZE] = {'\n'};
int ret = 0;
int i;
while (readSize = read(cfd, buff, sizeof(buff)))
{
if (readSize == -1)
{
perror("read");
return -1;
}
for (i = 0; i < strlen(buff); i++)
{
buff[i] += 'a' - 'A';
}
writeSize = write(cfd, buff, strlen(buff));
if (writeSize == -1)
{
perror("write");
return -1;
}
memset(buff, 0, sizeof(buff));
}
}
int main()
{
int listen_sockfd;
int ret;
struct sockaddr_in server_addr; // 服务器地址结构
struct sockaddr_in client_addr; // 客户端的地址
// 创建监听套接字
listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sockfd == -1)
{
perror("create socket error");
return -1;
}
// 初始化服务器地址结构
bzero(&server_addr, sizeof(server_addr)); // 将地址结构变量清零
server_addr.sin_family = AF_INET; // 选择IPV4地址
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听本地任意IP地址
server_addr.sin_port = htons(SERV_PORT); // 将本地端口号转化为网络端口号
// 绑定本地地址和端口号
ret = bind(listen_sockfd, (struct sockaddr *)&server_addr, sizeof (server_addr));
if (ret == -1)
{
perror ("bind error");
return -1;
}
// 监听套接字
ret = listen(listen_sockfd, 20);
if (ret == -1)
{
perror("listen error");
return -1;
}
signal(SIGCHLD,handle_child) ;
while(1)
{
int clientfd;
socklen_t client_len = sizeof(client_addr);
printf ("waiting for client to connect.....\n");
clientfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &client_len);
if (clientfd == -1)
{
perror("accept error");
return -1;
}
printf ("the client addr is %s\n", inet_ntoa(client_addr.sin_addr));
pid_t ret=fork() ;
switch(ret)
{
case 0 :
{
close(listen_sockfd) ;
// 客户端连接上, 进行通信,通信使用新的套接字
server_request(clientfd);
close(clientfd) ;
exit(0) ;
}
case -1 :
{
perror("fork") ;
return -1 ;
}
default :
{
close(clientfd) ;
break ;
}
}
}
return 0;
}
客户端代码段:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define SERV_PORT 9000
#define BUFF_SIZE 1024
int ask_server(int sfd)
{
char buff[BUFF_SIZE] = {0};
//fgets(buff, sizeof(buff), stdin);
while (1)
{
memset(buff, 0, sizeof(buff));
scanf("%s", buff);
if (strncmp("end", buff, 3) == 0)
{
break;
}
int writeSize = write(sfd, buff, strlen(buff));
if (writeSize == -1)
{
perror("write");
return -1;
}
memset(buff, 0, sizeof(buff));
int readSize = read(sfd, buff, sizeof(buff));
if (readSize == -1)
{
perror("read");
return -1;
}
printf ("read bytes : %d buff: %s\n", readSize, buff);
}
}
int main(int argc, char *argv[])
{
int server_sockfd;
int ret;
struct sockaddr_in client_addr;
if (argc != 2)
{
printf ("Usage:./client IP_ADDRESS\n");
return -1;
}
// 创建监听套接字
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (server_sockfd == -1)
{
perror("create socket error");
return -1;
}
// 初始化服务器地址结构
bzero(&client_addr, sizeof(client_addr)); // 将地址结构变量清零
client_addr.sin_family = AF_INET; // 选择IPV4地址
inet_aton(argv[1], &client_addr.sin_addr); // 填写服务器地址
client_addr.sin_port = htons(SERV_PORT); // 填写服务器端口
// 连接服务器
ret = connect(server_sockfd, (struct sockaddr *)&client_addr, sizeof (client_addr));
if (ret != 0)
{
perror("connect error");
return -1;
}
ask_server(server_sockfd);
close(server_sockfd);
return 0;
}
其实还有其他一些方法 比如线程之类的 因而我们要不断积累 提高自己的水平