服务端(Linux版)

#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAX 80
#define PORT 2087
#define SA struct sockaddr

// Function designed for chat between client and server.
void func(int sockfd)
{
    char buff[MAX];
    for(;;)
    {
        bzero(buff, sizeof(buff));
        recv(sockfd, buff, sizeof(buff), 0);
        if ((strncmp(buff, "exit", 4)) == 0) {
            printf("Client Exit...\n");
            break;
        }        
        printf("From Client : %s", buff);
        send(sockfd, buff, sizeof(buff), 0);
    }
}

static void sig_handler(int sig){
    
    int retval;
    
    if ( sig == SIGCHLD ){ 
        // 等待子程序的結束狀態
        wait(&retval);
        
        printf("CATCH SIGNAL PID=%d\n",getpid());
    }
}
  
// Driver function
int main(void)
{
    int sockfd, connfd;
    struct sockaddr_in servaddr, cli;
    socklen_t len;
    pid_t pid;
  
    // socket create and verification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        printf("socket creation failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully created..\n");
    
    bzero(&servaddr, sizeof(servaddr));
  
    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(PORT);
    
    int reuse = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(int)) == -1)
        printf("Can't set the reuse option on the socket");
  
    // Binding newly created socket to given IP and verification
    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
        printf("socket bind failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully binded..\n");
  
    // Now server is ready to listen and verification
    if ((listen(sockfd, 5)) != 0) {
        printf("Listen failed...\n");
        exit(0);
    }
    else
        printf("Server listening..\n");
        
  
    while(1)
    {
        // Accept the data packet from client and verification
        len = sizeof(cli);        
        connfd = accept(sockfd, (SA*)&cli, &len);
        if (connfd < 0) {
            printf("server acccept failed...\n");
            exit(0);
        }
        else
            printf("server acccept the client...\n");
        
        // 呼叫 signal 來接收 SIGCHLD 信號
        signal(SIGCHLD,sig_handler);
        
        pid = fork();
        
        if(pid < 0)
            printf("ERROR on fork");
        
        if(pid == 0)
        {
            close(sockfd);
            
            // Function for chatting between client and server
            func(connfd);
            close(connfd);
            exit(0);            
        }
        else
        {
            close(connfd);
        }
            
    }    
  
    // After chatting close the socket
    close(sockfd);
    
    return 0;
}

客户端(Windows版)

#include <stdio.h>
#include <winsock2.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <ws2tcpip.h>
#define MAX 80
#define PORT 2087
#define SA struct sockaddr
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)  
#define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0)

#pragma comment(lib,"ws2_32.lib") //Winsock Library
#pragma warning(disable:4996)

void func(int sockfd)
{
    char buff[MAX];
    int n;
    for (;;) {
        bzero(buff, sizeof(buff));
        printf("Enter the string : ");
        n = 0;
        while ((buff[n++] = getchar()) != '\n')
            ;
        send(sockfd, buff, sizeof(buff),0);
        bzero(buff, sizeof(buff));
        recv(sockfd, buff, sizeof(buff),0);
        printf("From Server : %s", buff);
        if ((strncmp(buff, "exit", 4)) == 0) {
            printf("Client Exit...\n");
            break;
        }
    }
}

int main(void)
{
    WSADATA wsa;
    int sockfd;
    struct sockaddr_in servaddr;

    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
        printf("Failed. Error Code : %d", WSAGetLastError());
        return 1;
    }
    printf("Initialised.\n");

    // socket create and varification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        printf("socket creation failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully created..\n");
    bzero(&servaddr, sizeof(servaddr));

    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr("192.168.1.234");
    servaddr.sin_port = htons(PORT);

    // connect the client socket to server socket
    if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
        printf("connection with the server failed...\n");
        exit(0);
    }
    else
        printf("connected to the server..\n");

    // function for chat
    func(sockfd);

    // close the socket
    closesocket(sockfd);

    WSACleanup();

    return 0;
}

服务端使用fork()创建多进程,可同时处理多个客户端的通信,另外也使用SIGCHLD信号来处理僵尸子进程。

标签: none

评论已关闭