Linux TCP服务器客户端

服务器端

cpp 复制代码
#include <sys/types.h>          
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, char *argv[]){
    if(argc != 3){
        fprintf(stderr, "Usage: %s <IP> <Port>\n", argv[0]); // 修正:提供完整的错误信息
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in my_addr, oth_addr;
    ssize_t recv_data;
    char buf[250];

    int socket_ret = socket(AF_INET, SOCK_STREAM, 0);
    if(socket_ret < 0){
        perror("socket"); // 修正:提供完整的错误信息
        exit(EXIT_FAILURE);
    }

    memset(&my_addr, 0, sizeof(my_addr)); // 修正:使用memset替代bzero
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(atoi(argv[2])); // 注意:如果atoi(argv[2])结果过大,可能会溢出
    my_addr.sin_addr.s_addr = inet_addr(argv[1]); // 注意:如果argv[1]不是有效的IP地址,这里会返回INADDR_NONE

    if(bind(socket_ret, (const struct sockaddr *)&my_addr, sizeof(my_addr)) < 0){
        perror("bind"); // 修正:提供完整的错误信息
        exit(EXIT_FAILURE);
    }

    if(listen(socket_ret, 10) < 0){
        perror("listen"); // 修正:提供完整的错误信息
        exit(EXIT_FAILURE);       
    }

    socklen_t len = sizeof(oth_addr);
    while(1){
        int client_socket = accept(socket_ret, (struct sockaddr *)&oth_addr, &len); // 修正:使用更明确的变量名

        if(client_socket < 0){
            perror("accept"); // 修正:提供完整的错误信息
            continue; // 修正:不退出程序,而是继续监听
        }

        printf("客户端地址为: %s\n", inet_ntoa(oth_addr.sin_addr)); // 修正:添加换行符\n

        memset(buf, 0, sizeof(buf)); // 修正:使用memset替代bzero
		while (1)
		{
		recv_data = recv(client_socket, buf, sizeof(buf) - 1, 0); // 修正:使用client_socket接收数据,并确保buf不会溢出
        if(recv_data > 0){
            printf("客户端发来:%s\n", buf); // 修正:添加换行符\n
        }

		}
		
      
        //close(client_socket); // 修正:关闭客户端套接字
    }

    // 注意:正常情况下,服务器套接字不应该在这里关闭,因为它需要持续监听新的连接
    // close(socket_ret); // 这行代码应该被注释掉或移除

    return 0;
}

客户端

cpp 复制代码
#include <sys/types.h>          
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, char *argv[]){
    if(argc != 3){
        fprintf(stderr, "Usage: %s <IP> <Port>\n", argv[0]); // 修正:提供完整的错误信息
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in my_addr, oth_addr;
    ssize_t recv_data;
    char buf[250];

    int socket_ret = socket(AF_INET, SOCK_STREAM, 0);
    if(socket_ret < 0){
        perror("socket"); // 修正:提供完整的错误信息
        exit(EXIT_FAILURE);
    }

    memset(&my_addr, 0, sizeof(my_addr)); // 修正:使用memset替代bzero
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(atoi(argv[2])); // 注意:如果atoi(argv[2])结果过大,可能会溢出
    my_addr.sin_addr.s_addr = inet_addr(argv[1]); // 注意:如果argv[1]不是有效的IP地址,这里会返回INADDR_NONE


	/*
	客户端不用绑定地址
    if(bind(socket_ret, (const struct sockaddr *)&my_addr, sizeof(my_addr)) < 0){
        perror("bind"); // 修正:提供完整的错误信息
        exit(EXIT_FAILURE);
    }
	*/
	/*客户端不用监听
    if(listen(socket_ret, 10) < 0){
        perror("listen"); // 修正:提供完整的错误信息
        exit(EXIT_FAILURE);       
    }
	*/
	int connect_ret = connect(socket_ret, (const struct sockaddr *)&my_addr, sizeof(my_addr));
	if (connect_ret < 0)
	{
		perror("connect");
		exit(1);
	}
	
    //socklen_t len = sizeof(oth_addr);
    while(1){
		/*
		客户端不需要等待自己连接
        int client_socket = accept(socket_ret, (struct sockaddr *)&oth_addr, &len); // 修正:使用更明确的变量名

        if(client_socket < 0){
            perror("accept"); // 修正:提供完整的错误信息
            continue; // 修正:不退出程序,而是继续监听
        }
		*/

        //printf("客户端地址为: %s\n", inet_ntoa(oth_addr.sin_addr)); // 修正:添加换行符\n

        memset(buf, 0, sizeof(buf)); // 修正:使用memset替代bzero
		while (1)
		{
		fgets(buf, sizeof(buf), stdin);
		recv_data = send(socket_ret, buf, sizeof(buf) - 1, 0); // 修正:使用client_socket接收数据,并确保buf不会溢出
        //if(recv_data > 0){
        //   printf("服务器发来:%s\n", buf); // 修正:添加换行符\n
        //}

		}
		
      
        //close(client_socket); // 修正:关闭客户端套接字
    }

    // 注意:正常情况下,服务器套接字不应该在这里关闭,因为它需要持续监听新的连接
    // close(socket_ret); // 这行代码应该被注释掉或移除

    return 0;
}
相关推荐
啊森要自信21 分钟前
【linux学习指南】VSCode部署Ubantu云服务器,与Xshell进行本地通信文件编写
linux·服务器·ide·vscode·ubuntu
ubuntu180421 分钟前
linux001.在Oracle VM VirtualBox中ubuntu虚拟系统扩容
linux·运维·ubuntu
最后一个bug23 分钟前
分享一些关于 C 函数与 lua 交互的实际项目案例
linux·c语言·嵌入式硬件·lua
皓月盈江25 分钟前
Linux debian系统安装ClamTk开源图形用户界面(GUI)杀毒软件
linux·运维·debian·clamav·clamtk·开源杀毒
最后一个bug43 分钟前
C函数如何返回参数lua使用
linux·c语言·开发语言·嵌入式硬件·lua
雷神乐乐1 小时前
ServletConfig、ServletContext、HttpServletRequest与HttpServletResponse常见API
java·服务器·前端·javaweb·tomcat8
Crossoads1 小时前
【汇编语言】更灵活的定位内存地址的方法(二)—— 从 [bx+idata] 到 [bx+si+idata]:让你灵活的访问内存
android·java·服务器·网络协议·tcp/ip·机器学习·汇编语言
酆訫鎻嗳1 小时前
ubuntu固定ip
linux·运维·ubuntu
188_djh1 小时前
# ubuntu 安装的pycharm不能输入中文的解决方法
linux·ubuntu·pycharm·fcitx·export·pycharm不能输入中文·zh_cn.utf-8
vvw&1 小时前
如何在 Ubuntu 上安装 Jellyfin 媒体服务器
linux·运维·服务器·ubuntu·媒体·nas·jellyfin