socket通信的简单实现

6 篇文章 0 订阅

感觉socket的用法还是需要好好耐心的研究一下,先把理论的看懂,包括什么是socket,有哪些数据结构,哪些重要的函数和原理,再把人家的代码一句句看懂,最后最好自己写出来实践一下。不管的写的怎么样,总是自己的代码最好看懂。而且自己写的东西要负责,毕竟还是自己看的多。

下面是我参考人家的代码(其实都差不多),修修补补的写的一个实例,因为在Linux下的socket实现比较容易,更容易帮助理解socket的用法和原理。但是功能也比较简单,写的不清楚的请不吝赐教!

server.c

/*
 * Filename: server.c 
 * version 1.0
 * Author :	Halfish
 * Last edit time: March 2nd, 2014
 */

#include <netinet/in.h>   // for sockaddr_in
#include <sys/types.h>    // for socket
#include <sys/socket.h>   // for socket
#include <stdio.h>        // for printf
#include <errno.h>        // for errno
#include <stdlib.h>       // for exit
#include <string.h>       // for memset

#define SERVER_PORT   6666 
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024


int main(int argc, char const *argv[])
{

	// 设置一个服务器端的socket地址结构server_addr,代表服务器internet地址, 端口
	struct sockaddr_in server_addr;

	int server_socket_fd; // 服务器端的文件描述符

	// define buffer to receive/send string from/to client
	char buffer_receive[BUFFER_SIZE];
	memset(buffer_receive, 0, BUFFER_SIZE);
	char buffer_send[BUFFER_SIZE];
	memset(buffer_send, 0, BUFFER_SIZE);


   /*
	* try to initialize to server address
	*/
	memset(&server_addr, 0, sizeof(server_addr)); //把一段内存区的内容全部设置为0
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);


   /*
	* try to creat a server socket
	*/
	server_socket_fd = socket(AF_INET, SOCK_STREAM, 0); 
	if (server_socket_fd == -1)
	{
		// only return -1 means fail and set errno simultaneously
		printf("	Failed to creat a socket for server...\n");
		printf("	(errno: %d) %s\n", errno, strerror(errno) );
		return 1;
	}	
	else
	{
		printf("	Successfully creat a socket for server...\n");
	}
		

   /*
	* try to bind the server_socket_fd and server_addr
	*/
	if( bind(server_socket_fd,(struct sockaddr*)&server_addr, sizeof(server_addr) ) == -1)
    {
    	// only return -1 means fail and set errno simultaneously
        printf("	Failed to bind this port: %d \n", SERVER_PORT); 
        printf("	(errno: %d) %s\n", errno, strerror(errno) );
        return 1;
    } 
    else 
    {
    	// only bind returns 0 means bind successfully ?!
        printf("	Bind successfully\n");
    }


   /*
    * the server begins to listen
    */
    if ( listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE) == -1)
    {
        printf("	Failed to listen..."); 
        printf("	(errno: %d) %s \n", errno, strerror(errno));
        return 1;
    }
    else 
    {
        printf("	Server is listening...\n");
    }


   /*
    * begin connections to multiple clients
    */
    while(1) 
    {
		struct sockaddr_in client_address;
        socklen_t length = sizeof(client_address);

       /*
        *
        * 接受一个到server_socket代表的socket的一个连接
        * 如果没有连接请求,就等待到有连接请求--这是accept函数的特性
        * accept函数返回一个新的socket,这个socket(new_server_socket_fd)用于同连接到的客户的通信
        * new_server_socket_fd代表了服务器和客户端之间的一个通信通道
        * accept函数把连接到的客户端信息填写到客户端的socket地址结构client_address中
        *
        */
        int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_address, &length);
        if ( new_server_socket_fd < 0)
        {
            printf("	Failed to accept a connection from to client!\n");
            printf("	(errno: %d) %s\n", errno, strerror(errno) );
            break;
        } 
        else
        {
            printf("	Accepted a client successfully\n");
        }

// Thread added here

        // accepted connection, begin a dead loop to receive information from one specific client
        while(1)
        {
           /*
        	* recieve data from client
        	*/
        	memset(buffer_receive, 0, BUFFER_SIZE);

			length = recv(new_server_socket_fd, buffer_receive, BUFFER_SIZE, 0);
			if (length < 0)
			{
				printf("	Failed to recieve data from client. \n" );
				printf("	(errno: %d) %s\n", errno, strerror(errno) );
				continue;
			}
			else
			{
				printf("	Client said:");
				printf("	%s\n", buffer_receive);
			}

           /*
            * scanf from stdin continuously and send to client simutaneously
        	*/
        	printf("	Server(it's me) said:	");
        	memset(buffer_send, 0, BUFFER_SIZE);
        	scanf("%s", buffer_send);       	
        	if (send(new_server_socket_fd, buffer_send, sizeof(buffer_send), 0) < 0) 
        	{
        		printf("	Failed to send data to client. \n" );
				printf("	(errno: %d) %s\n", errno, strerror(errno) );
				continue;
        	}      	
        } // end of while(1)
   		close(new_server_socket_fd);
    }

    close(server_socket_fd);

	return 0;
}

client.c

/*
 * Filename: client.c 
 * version 1.0
 * Author :	Halfish
 * Last edit time: March 2nd, 2014
 */

#include <netinet/in.h>   // for sockaddr_in
#include <sys/types.h>    // for socket
#include <sys/socket.h>   // for socket
#include <stdio.h>        // for printf
#include <errno.h>        // for errno
#include <stdlib.h>       // for exit
#include <string.h>       // for memset

#define SERVER_PORT  6666 
#define BUFFER_SIZE  1024


int main(int argc, char const *argv[])
{

    if (argc != 2)
    {
        printf("    You must tell me the address of server! \n");
        return 0;
    }

   /*
    * initilize client
    */
    int client_socket_fd = socket(AF_INET,SOCK_STREAM,0);
    if (client_socket_fd == -1)
    {
        // only return -1 means fail and set errno simultaneously
        printf("    Failed to creat a socket for client.\n");
        printf("    (errno: %d) %s\n", errno, strerror(errno) );
        return 1;
    }
    else 
    {
        printf("    Successfully initilize the client !\n");
    }


   /*
    * initilize server address
    */
    struct sockaddr_in server_address;
    memset(&server_address, 0, sizeof(server_address));
    server_address.sin_family = AF_INET;

    if (inet_aton(argv[1],&server_address.sin_addr) == 0)  // inet_aton() = address to number
    {
        printf("    Server's IP address error!\n");
        printf("    (errno: %d) %s\n", errno, strerror(errno) );
        return 1;
    }
    server_address.sin_port = htons(SERVER_PORT);
    socklen_t server_addr_length = sizeof(server_address);

   /*
    * begin to connect to server
    */
    if ( connect(client_socket_fd, (struct sockaddr*) &server_address, server_addr_length) == -1)
    {
        printf("    Can not connect to %s!\n", argv[1]);
        printf("    (errno: %d) %s\n", errno, strerror(errno) );        return 1;
    }
    else
    {
        printf("    Successfully connect to server! \n");
    }


   /*
    * define buffer to receive/send string from/to server
    */
    char buffer_receive[BUFFER_SIZE]; 
    char buffer_send[BUFFER_SIZE];
    memset(buffer_receive, 0, BUFFER_SIZE);
    memset(buffer_send, 0, BUFFER_SIZE);

    strcpy(buffer_send, "    I am the client, can you hear me ? ");
    if (send(client_socket_fd, buffer_send, sizeof(buffer_send), 0) < 0) 
    {
        printf("    Failed to send data to client. \n" );
        printf("    (errno: %d) %s\n", errno, strerror(errno) );
        return 0;
    }     

    // accepted connection, begin a dead loop to receive information from one specific client
    int i = 1;
    while(i)
    {
        printf("%d\n", i);
        ++ i;
        /*
        * recieve data from server
        */
        memset(buffer_receive, 0, BUFFER_SIZE);
        socklen_t length = sizeof(server_address);

        length = recv(client_socket_fd, buffer_receive, BUFFER_SIZE, 0);
        if (length < 0)
        {
            printf("    Failed to recieve data from server. \n" );
            printf("    (errno: %d) %s\n", errno, strerror(errno) );
            continue;
        }
        else
        {
            printf("    Server said:");
            printf("    %s\n", buffer_receive);
        }

       /*
        * scanf from stdin continuously and send to server simutaneously
        */
        printf("    Client(it's me) said:   ");
        memset(buffer_send, 0, BUFFER_SIZE);
        scanf("%s", buffer_send);           
        if (send(client_socket_fd, buffer_send, sizeof(buffer_send), 0) < 0) 
        {
            printf("    Failed to send data to server. \n" );
            printf("    (errno: %d) %s\n", errno, strerror(errno) );
            continue;
        }       
    } // end of while(1)      

    close(client_socket_fd);

	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值