TCP通信程序

如题,这是一段基于socket的TCP通信代码

服务器程序

#include <fcntl.h> 
#include <unistd.h> 
#include<arpa/inet.h>
#include<netinet/in.h>
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>

int main(int argc, char *argv[]) {
        int sockfd, new_fd;//这里有两个socket描述符分别存放服务器和客户端的地址、端口等信息
        struct sockaddr_in server_addr, client_addr;//服务器地址和客户端地址
        int sin_size,portnumber;//对方的地址长度、服务器端口号
        char input[1024];//input[]数组存放发送的消息
        char buffer[1024];//buffer[]数组存放接收的消息
        int nbytes;
        portnumber = atoi(argv[1]);//指定端口号
//创建socket
        if (1==(sockfd = socket(AF_INET, SOCK_STREAM, 0)) ) { //socket()调用出错
                perror("socket");
                exit(1);
        }
        bzero(&server_addr, sizeof(struct sockaddr_in));//将服务器地址清零
        server_addr.sin_family = AF_INET;
//设置地址类型为AF_INET
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//设置网络地址为INADDR_ANY,INADDR_ANY表示本机的任意的ip地址
        server_addr.sin_port = htons(portnumber);
//设置服务器端口号
//绑定sockfd
        bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr) );
//在sockfd上侦听,最多允许5个连接
        listen(sockfd, 5);
        while (1) {
//先清空客户端信息,防止出错
                bzero(&client_addr, sizeof(struct sockaddr_in));
                sin_size = sizeof(client_addr);
//接受连接,将客户端信息存入client_addr,得到new_fd
                new_fd = accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size);
                if (! getpeername(new_fd, (struct sockaddr *)&client_addr, &sin_size)) {
                        printf("clinet's IP:%s\n", inet_ntoa(client_addr.sin_addr));
                }
                memset(input,0,strlen(input));
                printf("I have sent:");
                fgets(input, 1000, stdin); //输入字符,存入input
                send(new_fd, input, strlen(input), 0);
//将input发给客户端
                if (-1 == (nbytes = recv(new_fd, buffer, 1024, 0))) {
//接收客户端发来的数据
                perror("read");
                exit(1);
                }
                buffer[nbytes] = '\0';
                printf("I have received:%s\n", buffer);
                memset(buffer,0,nbytes);
        }
        close(new_fd);
//关闭socket描述符
        close(sockfd);
//关闭socket描述符
        exit(0);
}

客户端程序

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
int main(int argc, char *argv[]) {
        //3个参数,命令名 ip 端口
        int sockfd;
        char input[1024];
        char buffer[1024];
        struct sockaddr_in server_addr;
        int nbytes;
        int portnumber;
        portnumber = atoi(argv[2]); //ascii转为int,得到端口号
//创建socket描述符sockfd
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        bzero(&server_addr, sizeof(struct sockaddr_in));//将服务器地址清零
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(portnumber); //字节序转换
        server_addr.sin_addr.s_addr = inet_addr(argv[1]); //IP
        if (-1 == connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))) { //发起连接
                perror("socket");
                exit(1);
        }
while(1){
        memset(buffer, 0, nbytes);
        if (-1 == (nbytes = recv(sockfd, buffer, 1024, 0))) {
                //接收服务器发来的数据
                perror("read");
                exit(1);
        }
        buffer[nbytes] = '\0';
        printf("I have received:%s\n", buffer);
        printf("I have sent:");
        fgets(input, 1000, stdin); //输入字符,存入input
        send(sockfd, input, strlen(input), 0);
        memset(input, 0, strlen(input));
        }
        close(sockfd);//关闭socket描述符
        exit(0);
}
                                                                              

分别将服务器端程序编译为tcpserver,客户端程序编译为tcpclien,在虚拟机上使用127.0.0.1进行测试,以端口号8888为例:

首先终端一运行tcpserver

tcpserver 8888

在另一终端运行客户端

tcpclient 127.0.0.1 8888

这段代码只能实现一次半双工通信,可以在此基础上结合进程或线程实现全双工通信。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的C++ TCP通信程序的示例: ```cpp #include <iostream> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") int main() { // 初始化Winsock WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { std::cout << "Failed to initialize winsock" << std::endl; return 1; } // 创建套接字 SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (serverSocket == INVALID_SOCKET) { std::cout << "Failed to create socket" << std::endl; WSACleanup(); return 1; } // 设置服务器地址和端口 sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = INADDR_ANY; serverAddress.sin_port = htons(8888); // 绑定套接字 if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR) { std::cout << "Failed to bind socket" << std::endl; closesocket(serverSocket); WSACleanup(); return 1; } // 监听连接请求 if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) { std::cout << "Failed to listen on socket" << std::endl; closesocket(serverSocket); WSACleanup(); return 1; } std::cout << "Server started, waiting for connections..." << std::endl; // 接受连接请求 SOCKET clientSocket; sockaddr_in clientAddress; int clientAddressSize = sizeof(clientAddress); clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressSize); if (clientSocket == INVALID_SOCKET) { std::cout << "Failed to accept connection" << std::endl; closesocket(serverSocket); WSACleanup(); return 1; } std::cout << "Client connected" << std::endl; // 接收和发送数据 char buffer[1024]; while (true) { memset(buffer, 0, sizeof(buffer)); int bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0); if (bytesRead <= 0) { std::cout << "Connection closed by client" << std::endl; break; } std::cout << "Received: " << buffer << std::endl; std::string response = "Hello from server"; send(clientSocket, response.c_str(), response.length(), 0); } // 关闭套接字和清理Winsock closesocket(clientSocket); closesocket(serverSocket); WSACleanup(); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值