tcp_server和tcp_client

本文提供了TCP服务器与客户端的C语言实现代码示例。服务器能够接收来自客户端的消息并回显,而客户端则可以向服务器发送消息。代码展示了如何创建套接字、进行绑定、监听及接受连接等关键步骤。

tcp_server代码如下:

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

static void usage(const char *proc)
{
    printf("Usage: %s [local_ip] [local_port]\n",proc);
}

int startup(const char *ip,int port)
{
    int sock = socket(AF_INET,SOCK_STREAM, 0);
        if(sock < 0){
            perror("socket");
            exit(2);
        }

    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    local.sin_addr.s_addr = inet_addr(ip);

    if(bind(sock, (struct sockaddr*)&local, sizeof(local))<0){
        perror("bind");
        exit(3);
    }
    if(listen(sock, 10)<0){
        perror("listen");
        exit(4);
    }
    return sock;
}

// ./tcp_server ip port
int main(int argc, char *argv[])
{
    if(argc != 3){
        usage(argv[0]);
        return 1;
    }
int listen_sock = startup(argv[1],atoi(argv[2]));

while(1){
    struct sockaddr_in client;
    socklen_t len = sizeof(client);

    int new_sock = accept(listen_sock,\
            (struct sockaddr*)&client, &len);
    if(new_sock < 0){
        perror("accept");
        continue;
    }
    printf("get a new cilent, %s:%d\n",\
            inet_ntoa(client.sin_addr), ntohs(client.sin_port));

    while(1){
        char buf[1024];
        ssize_t s = read(new_sock, buf, sizeof(buf)-1);
        if(s>0){
            buf[s] = 0;
            printf("client: %s\n", buf);
            write(new_sock, buf, strlen(buf));
        }else if(s == 0){
            close(new_sock);
            printf("client quit...\n");
            break;
        }else{
            perror("read");
            close(new_sock);
            break;
        }
    }
}
}

****

tcp_client代码如下:

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

static void usage(const char *proc)
{
    printf("Usage:%s[server_ip][server_port]\n",proc);
}
//./tcp client server-ip server-port
int main(int argc,char *argv[])
{
    if(argc !=3){
    usage(argv[0]);
    return 1;
    }

    int sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock<0){
    perror("socket");
    return 1;
    }
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[2]));
    server.sin_addr.s_addr = inet_addr(argv[1]);
    if(connect(sock,(struct sockaddr*)&server,\
                sizeof(server))<0){
        perror("connect");
        return 2;
    }
    char buf[1024];
    while(1){
        printf("Please Enter# ");
        fflush(stdout);
        ssize_t s = read(0,buf,sizeof(buf)-1);
        if(s>0){
        buf[s-1] = 0;
        write(sock, buf, strlen(buf));
        s = read(sock, buf, sizeof(buf)-1);
        if(s>0){
        buf[s] = 0;
        printf("server echo# %s\n",buf);
        }
        }
    }
}

client终止时自动关闭socket描述符,server的tcp 连接收到client发的FIN段后处于TIME_WITE状态。

<think>好的,我现在要解释用户提供的Makefile代码。首先,我需要回忆Makefile的基本结构语法,确保自己理解正确。用户给出的代码看起来是一个用于编译TCP客户端服务器的Makefile。接下来,我需要逐行分析每个部分的作用。 首先看第一行:CC=gcc。这应该是设置编译器变量,指定使用gcc作为C编译器。然后是CFLAGS=-Wall,这里设置了编译选项,启用所有警告。不过注意到在后面的规则中,直接用了-Wall而不是引用CFLAGS变量,这可能是个问题或者用户有意为之? 接下来是all目标,依赖tcp_clienttcp_server。这说明默认情况下,执行make命令会构建这两个可执行文件。不过当前的Makefile中只有tcp_server的规则,没有tcp_client的规则,这可能是个遗漏或者用户没给出全部代码?需要指出这一点。 然后看tcp_server目标,它依赖于tcp_server.c,编译命令使用gcc并链接pthread库。这里需要注意编译命令是否使用了CFLAGS变量,但实际用的是-Wall,可能用户应该用$(CFLAGS)来保持一致性。另外,-lpthread的位置是否正确?通常链接库应该放在命令末尾,这里没问题。 clean目标用于删除生成的可执行文件,但同样缺少tcp_client的清理,这可能是因为tcp_client的规则不存在,所以clean里可能也没必要,或者用户需要补充。 总结问题点:缺少tcp_client的构建规则,CFLAGS变量未被使用,可能导致后续维护不便。需要向用户指出这些潜在问题,同时解释现有的结构。同时,确认Makefile中的缩进是否是制表符,因为这是Makefile的语法要求,用户提供的代码中缩进正确。 最后,用中文清晰分点解释各部分功能,并指出可能的改进建议,确保用户理解整个Makefile的结构潜在问题。</think>这是一个用于编译TCP客户端/服务器程序的Makefile,我为您逐步分解其结构功能: 1. **变量定义** - `CC = gcc`:定义编译器变量,指定使用GCC编译C程序 - `CFLAGS = -Wall`:设置编译选项,`-Wall`表示启用所有警告信息 2. **默认目标** - `all: tcp_client tcp_server`:定义默认构建目标,当直接运行`make`时会编译这两个可执行文件 3. **服务器编译规则** ```makefile tcp_server: tcp_server.c $(CC) tcp_server.c -Wall -o tcp_server -lpthread ``` - 目标文件`tcp_server`依赖`tcp_server.c`源文件 - 编译命令使用gcc编译器,`-lpthread`表示链接POSIX线程库 - 注意这里直接使用`-Wall`而未使用`$(CFLAGS)`变量 4. **清理规则** - `clean: rm tcp_server tcp_client`:删除生成的可执行文件 ⚠️ **需要注意的问题**: 1. 缺失`tcp_client`的构建规则:当前文件只定义了server的编译规则,client部分需要补充 2. 推荐使用变量:应将`-Wall`替换为`$(CFLAGS)`以保持统一 3. 可添加`.PHONY`声明:建议添加`.PHONY: all clean`避免与同名文件冲突 **建议的完整Makefile**: ```makefile CC = gcc CFLAGS = -Wall -Wextra .PHONY: all clean all: tcp_client tcp_server tcp_server: tcp_server.c $(CC) $(CFLAGS) $< -o $@ -lpthread tcp_client: tcp_client.c $(CC) $(CFLAGS) $< -o $@ clean: rm -f tcp_server tcp_client ``` **使用说明**: - 编译:`make` 或 `make all` - 清理:`make clean` - 单独编译server:`make tcp_server`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值