1. 程式人生 > >[C語言] 基於Linux的一對一Socket簡易聊天程式例項

[C語言] 基於Linux的一對一Socket簡易聊天程式例項

如題

此篇示例為Socket網路程式的基本範例,於LINUX環境下編譯並執行通過

使用方法請參閱程式碼,程式碼不復雜

chatclient.c

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
 
#define MAXBUF 1024

int main(int argc, char *argv[])
{
    int s, len;
    struct sockaddr_in addr;
    char buffer[MAXBUF + 1];
    fd_set afds, rfds;
    struct timeval tv;
   	
	switch (argc)
	{
		case 3:
			break;
		default:
			printf("usage: chatclient ip port\n");
			exit(1);
	}
	
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
        printf("socket error!\n");
		return -1;
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
	bzero((void*)&addr.sin_zero,8);
    if(inet_aton(argv[1], (struct in_addr *) &addr.sin_addr.s_addr) == 0)
	{
        perror(argv[1]);
        exit(errno);
    }

    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) != 0) {
        perror("Connect ");
        exit(errno);
    }
 
    printf("\nclient: ready for chatting!\n");
    while(1)
	{
		int ret;
        FD_ZERO(&rfds);
		FD_ZERO(&afds);
		FD_SET(0, &afds);
		FD_SET(s, &afds);
        tv.tv_sec = 1;
        tv.tv_usec = 0; // set select time-out = 1s
		memcpy(&rfds, &afds, sizeof(rfds));
        ret = select(s + 1, &rfds, (fd_set *)0, (fd_set *)0, &tv);
        if(ret < 0)
		{
            printf("client: select error %s", strerror(errno));
            break;
        }
		else if(ret == 0)
		{
            continue;
        }
		else
		{
			if(FD_ISSET(0, &rfds)) //read user input process
			{
                bzero(buffer, MAXBUF + 1);
                fgets(buffer, MAXBUF, stdin);
                if(!strncasecmp(buffer, "quit", 4))
				{
                    printf("client: exit chatting!\n");
                    break;
                }
                len = send(s, buffer, strlen(buffer) - 1, 0);
                if(len < 0)
				{
                    printf("client: send failed\n");
                    break;
                }
				else
                    printf("client: %s\n",buffer);
            }
            if(FD_ISSET(s, &rfds)) //receive msg through socket
			{
                bzero(buffer, MAXBUF + 1);
                len = recv(s, buffer, MAXBUF, 0);
                if(len > 0)
                    printf("client recv:'%s'\n",buffer);
                else {
                    if(len < 0)
                        printf("client: recv failed\n");
                    else
                        printf("client: session end, because the other one quit\n");
                    break;
                }
            }
        }
    }
    close(s);
    return 0;
}
chatserver.c
/**************************************************/
/* Chat - Server                                  */
/**************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
 
#define MAXBUF 1024
#define QLEN 5
 
int main(int argc, char *argv[])
{
	fd_set afds, rfds;
	struct sockaddr_in addr_host, addr_client;
    int msock, ssock;
    socklen_t len;
    unsigned int port;
    char buf[MAXBUF + 1];
    struct timeval tv;
    
	switch (argc)
	{
		case 2:
			port = atoi(argv[1]);
			break;
		default:
			printf("usage: chatserver port\n");
			exit(1);
	}
	
    msock=socket(AF_INET,SOCK_STREAM,0);
	if(msock<0)
	{
		printf("socket error!\n");
		return -1;
	}

    addr_host.sin_family = AF_INET;
	addr_host.sin_addr.s_addr=htonl(INADDR_ANY);
    addr_host.sin_port = htons(port);
	bzero((void *)&addr_host.sin_zero, 8);
   
 
    if(bind(msock,(struct sockaddr*)&addr_host,sizeof(addr_host))<0)
	{
		close(msock);
		printf("bind error!\n");
		return -1;
	}
	if(listen(msock,QLEN)<0)
	{
        printf("LISTEN error");
		return -1;
    }
 
    while(1)
	{
        printf("\nserver: waiting...\n");
        len = sizeof(struct sockaddr);
        if((ssock =accept(msock, (struct sockaddr *) &addr_client, &len)) == -1) {
            perror("accept");
            exit(errno);
        }
		else
            printf("server: got connection from %s, port %d, socket %d\n",
                   inet_ntoa(addr_client.sin_addr),
                   ntohs(addr_client.sin_port), ssock);
        printf("\nserver: ready for chatting!\n");
        while(1)
		{
			int ret;
            FD_ZERO(&rfds);
			FD_ZERO(&afds);
			FD_SET(0, &afds);
			FD_SET(ssock, &afds);
            tv.tv_sec = 1;
            tv.tv_usec = 0; // set select time-out = 1s
			memcpy(&rfds, &afds, sizeof(rfds));
            ret = select(ssock + 1, &rfds, (fd_set *)0, (fd_set *)0, &tv);
            if(ret < 0)
			{
                printf("server: select error %s", strerror(errno));
                break;
            }
			else if(ret == 0)
			{
                continue;
            }
			else
			{
                if(FD_ISSET(0, &rfds)) //read user input process
				{
                    bzero(buf, MAXBUF + 1);
                    fgets(buf, MAXBUF, stdin);
                    if(!strncasecmp(buf, "quit", 4))
					{
                        printf("server: exit chatting!\n");
                        break;
                    }
                    len = send(ssock, buf, strlen(buf) - 1, 0);
                    if(len > 0)
                        printf("server:%s\n",buf);
                    else
					{
                        printf("server:send failed\n");
                        break;
                    }
                }
                if(FD_ISSET(ssock, &rfds)) //receive msg through socket
				{
                    bzero(buf, MAXBUF + 1);
                    len = recv(ssock, buf, MAXBUF, 0);
                    if(len > 0)
                        printf("server recv:'%s'\n",buf);
                    else
					{
                        if(len < 0)
                            printf("server:recv failed\n");
                        else
                            printf("server: session end, because the other one quit\n");
                        break;
                    }
                }
            }
        }
        close(ssock);
		//decide whether continue chatting
        printf("Continue chatting?(no=>exit)");
        fflush(stdout);
        bzero(buf, MAXBUF + 1);
        fgets(buf, MAXBUF, stdin);
        if(!strncasecmp(buf, "no", 2))
		{
            printf("server: Terminating chat!\n");
            break;
        }
    }
 
    close(msock);
    return 0;
}