linux网络通信之tcp

微笑客户端

/*************************************************************************
	> File Name: client.c
	> Author: 联合作战实验室
	> Mail: v.manstein@qq.com
	> Created Time: Wed 22 Mar 2017 02:47:10 PM CST
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>

#define err_log(errlog) do{printf("%s: %s, %d", __FILE__, __func__, __LINE__);\
                          perror(errlog);}while(0)
#define N 128

int main(int argc, const char* argv[])
{
    int sockfd, acceptfd;// clinet sockfd
	char buf[N] = {};
	// 网络通信结构体对象
    struct sockaddr_in serveraddr;
    int addrlen = sizeof(struct sockaddr_in);

    if(argc < 3) {
        printf("usage: %s ipaddr port\n", argv[0]);
        exit(-1);
    } 
	// 创建套接字
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        err_log("socket error");
        exit(-1);
    }
	// 初始化网络通信结构体对象
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));
    // 客户端发起对服务器的链接通信访问请求        
    if(connect(sockfd, (struct sockaddr*)&serveraddr, 
               sizeof(struct sockaddr)) < 0) {
        err_log("connect error");
    }
    printf("client connect success\n");

    while(1) {
        printf("input:");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = '\0';
	// 发送消息
        if(send(sockfd, buf, N, 0) < 0) {
            err_log("send error");
        }

        if(strncmp(buf, "quit", 4) == 0 ) {
            break;
        }
	// 接受消息
        if(recv(sockfd, buf, N, 0) < 0) {
            err_log("recv error");
        }
        printf("%s\n", buf);
    }
    close(sockfd);

    return 0;

}
微笑服务器

/*************************************************************************
	> File Name: server.c
	> Author: 联合作战实验室
	> Mail: v.manstein@qq.com
	> Created Time: Wed 22 Mar 2017 02:47:10 PM CST
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>

#define err_log(errlog) do{printf("%s: %s, %d", __FILE__, __func__, __LINE__);\
                          perror(errlog);}while(0)
#define N 128
int main(int argc, const char* argv[])
{
    int sendbuf = 0; 
    int recvbuf = 0;
    int len;

    int sockfd, acceptfd;// clinet sockfd
    // 网络通信结构体
    //  struct sockaddr_in   {                                                   
    //      __SOCKADDR_COMMON (sin_);   // 地址族
    //      in_port_t sin_port;         /* Port number. 端口号 */
    //      struct in_addr sin_addr;    /* Internet address. ip地址  */
    //      /* Pad to size of `struct sockaddr'.  */
    //      unsigned char sin_zero[sizeof (struct sockaddr) -   
    //          __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) -
    //          sizeof (struct in_addr)];   // 占位填充,没有实际意义
    //  }; 
    struct sockaddr_in serveraddr, clinetaddr;
    int addrlen = sizeof(struct sockaddr_in);
    char buf[N] = {};

    if(argc < 3) {
        printf("usage: %s ipaddr port\n", argv[0]);
        exit(-1);
    } 

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        err_log("socket error");
        exit(-1);
    }
    serveraddr.sin_family = AF_INET;
    // inet_addr将点分十进制的ip地址,转换成本地地址进行存储(网络字节序的)
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    // htons将本机字节序转换为网络字节序
    serveraddr.sin_port = htons(atoi(argv[2]));
    // 将网络信息结构体和网络套接字绑定
    if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr_in)) < 0) {
        err_log("bind error");
    }
    // 设置监听队列,将网络套接字置于被动监听模式
    if(listen(sockfd, 5) < 0) {
        err_log("listen error");
    }
    // 接收客户端请求,反回一个与此客户端通信的套接字
    if((acceptfd = accept(sockfd, (struct sockaddr*)&clinetaddr, &addrlen)) < 0) {
        err_log("accept error");
    }
    
    printf("acceptfd: %d, %s, %d", acceptfd, inet_ntoa(clinetaddr.sin_addr), ntohs(clinetaddr.sin_port));
    while(1) {
        if(recv(acceptfd, buf, N, 0) < 0) {
            err_log("recv error");
        }
        if(getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &recvbuf, &len) == -1) { // 获取接收缓冲区大小
            err_log("getsockopt error: ");
        }

        printf("recvbuf length: %d\n", recvbuf);
        if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuf, &len) == -1) { // 获取发送缓冲区大小
            err_log("getsockopt error: ");
        }
        printf("sendbuf length: %d\n", sendbuf);

        printf("\naccept from clinet: %s\n", buf);
        if(strncmp(buf, "quit", 4) == 0 ) {
            break;
        }
        strcat(buf, "form server,");
        if(send(acceptfd, buf, N, 0) < 0) {
            err_log("send error");
        }

    }
    close(sockfd);
    close(acceptfd);

    return 0;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值