linux c socket之TCPEcho4

TCP客户端与服务器通信实现
本文详细介绍了TCP客户端和服务器的通信实现过程,包括创建套接字、设置服务器和客户端地址、连接、发送和接收数据等关键步骤。通过示例代码展示了如何在不同操作系统上进行网络编程。

1、客户端

/* 
 * File:   TCPEchoClient4.c
 * Author: 云守护 客户端
 *
 * Created on 2013年11月13日, 下午3:49
 */

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

int main(int argc, char** argv) {
    
    if(argc<3||argc>4)
    {
        DieWithUserMessage("param","<server Address><Echo Word>[<Server Port>]");
    }
    char* server_IP=argv[1];
    char* echoString=argv[2];
    in_port_t server_port=(argc==4)?atoi(argv[3]):7;
    int sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sock<0)
    {
        DieWithSystemMessage("socket failed!");
    }
    //配置服务端socket信息
    struct sockaddr_in server_addr;
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family=AF_INET;
    //转换地址,转换成网络地址
    int rtnVal=inet_pton(AF_INET,server_IP,&server_addr.sin_addr.s_addr);
    if(rtnVal==0)
        DieWithUserMessage("inet_pton failed!","invalid address string");
    else if(rtnVal<0)
    {
        DieWithSystemMessage("inet_pton failed!");
    }
    server_addr.sin_port=htons(server_port);
    if(connect(sock,(struct sockaddr*)&server_addr,sizeof(server_addr))<0)
    {
        DieWithSystemMessage("connect() failed!");
    }
    size_t echoStringLen=strlen(echoString);
    //发送数据,阻塞模式
    ssize_t numBytes=send(sock,echoString,echoStringLen,0);
    if(numBytes<0)
        DieWithSystemMessage("send() failed");
    else if(numBytes!=echoStringLen)
        DieWithUserMessage("send() ","sent unexpected number of bytes");
    unsigned int totalBytesRcvd=0;
    fputs("Received: ",stdout);
    while(totalBytesRcvd<echoStringLen)
    {
        char buffer[BUFSIZ];
        //接收数据
        numBytes=recv(sock,buffer,BUFSIZ-1,0);
        if(numBytes<0)
            DieWithSystemMessage("recv(0 failed!");
        else if(numBytes==0)
        {
            DieWithUserMessage("recv()","connection closed prematurely");
        }
        totalBytesRcvd+=numBytes;
        buffer[numBytes]='\0';
        fputs(buffer,stdout);
        
    }
    fputc('\n',stdout);
    close(sock);
    return (EXIT_SUCCESS);
}

/* 
 * File:   DieWithMessage.h
 * Author: root
 *
 * Created on 2013年11月13日, 下午3:52
 */

#ifndef DIEWITHMESSAGE_H
#define	DIEWITHMESSAGE_H

#ifdef	__cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
 void  DieWithUserMessage(const char *msg,const char * detail)
 {
     fputs(msg,stderr);
     fputs(":",stderr);
     fputs(detail,stderr);
     fputs("\n",stderr);
     exit(1);
 }
 void DieWithSystemMessage(const char* msg)
 {
     perror(msg);
     exit(1);
 }



#ifdef	__cplusplus
}
#endif

#endif	/* DIEWITHMESSAGE_H */


2、服务端

/* 
 * File:   TCPEchoServer4.c 服务端
 * Author: 云守护
 *
 * Created on 2013年11月14日, 上午10:10
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "DieWithMessage.h"
static const int MAXPENDING=10;
void HandleTCPClient(int client_sock)
{
    char buffer[BUFSIZ];
    //先接收客户端的数据
    ssize_t numBytesRcvd =recv(client_sock,buffer,BUFSIZ,0);
    if(numBytesRcvd<0)
        DieWithSystemMessage("recv() failed!");
    while(numBytesRcvd>0)
    {
        //发送数据回去
        ssize_t numBytesSent=send(client_sock,buffer,numBytesRcvd,0);
        if(numBytesSent<0)
            DieWithSystemMessage("send() failed!");
        else if(numBytesSent!=numBytesRcvd)
        {
            DieWithUserMessage("send()","sent unexpected number of bytes");
        }
        //继续接收数据
        numBytesRcvd=recv(client_sock,buffer,BUFSIZ,0);
        if(numBytesRcvd<0)
            DieWithSystemMessage("recv() failed!");
        
    }
    close(client_sock);
    
}
int main(int argc, char** argv) {
   
    if(argc!=2)
    {
        DieWithUserMessage("param","<Server Port>");
    }
    in_port_t server_port=atoi(argv[1]);
    //建立
    int server_sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(server_sock<0)
    {
        DieWithSystemMessage("socket() failed");
    }
    //配置服务器socket
    struct sockaddr_in server_addr;
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    server_addr.sin_port=htons(server_port);
    //绑定端口
    if(bind(server_sock,(struct sockaddr*)&server_addr,sizeof(server_addr))<0)
    {
        DieWithSystemMessage("bind() failed!");
    }
    //监听端口
    if(listen(server_sock,MAXPENDING)<0)
    {
        DieWithSystemMessage("listen(0 failed!");
    }
    printf("server start success on %d \n",server_port);
    for(;;)
    {
        //启动成功,等待客户端链接,
        //client_addr保存客户端地址信息
        struct sockaddr_in client_addr;
        socklen_t client_addr_len=sizeof(client_addr);
        //获取客户端socket
        int client_sock=accept(server_sock,(struct sockaddr*)&client_addr,&client_addr_len);
        if(client_sock<0)
        {
            DieWithSystemMessage("accept() failed!");
        }
        //获取客户端IP和端口
        char clientName[INET_ADDRSTRLEN];
        if(inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,clientName,sizeof(clientName))!=NULL)
        {
            printf("Handing Client %s /%d \n",clientName,ntohs(client_addr.sin_port));
        }else{
            puts("Unable to get client address!");        
        }
        //处理数据
        HandleTCPClient(client_sock);
    }
    
    return (EXIT_SUCCESS);
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值