Linux下Socket编程(TCP)

使用Linux提供的系统函数实现TCP通信。

通信步骤:

    服务器端:建立Socket->绑定到端口->开始监听->等待->有客户端连接->创建子进程(线程)开始通信->继续监听。

    客户端 :   建立Socket->发起向服务器的连接->连接成功->开始通信->通信结束,关闭Socket。


主要用到的函数:

socket,bind,listen,accept,send,recv,connect等。


已经通过测试的例子:

服务器端 Server.cpp:

/***************************************
在本机3333端口建立TCP监听,
有客户端连接后向其先发送一段消息,然后读取客户端的返回消息。
***************************************/
#include <iostream>
#include <string.h>//bzero()
#include <stdio.h>//perror
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>/**ip addr struct **/
#include <arpa/inet.h>


using namespace std;

int main()
{
    int sockfd,client_fd;
    int port=3333;
    struct sockaddr_in my_addr;/*本机地址信息结构体*/
    struct sockaddr_in rem_addr;//远程客户机地址信息

    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        perror("Socket error!");//创建socket出错
        exit(1);
    }
    else cout<<"socket success!"<< sockfd << endl;
    /*配置socket,IP和端口*/
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(port);//服务器监听端口号host to net
    my_addr.sin_addr.s_addr=INADDR_ANY;//在本机任何IP(全部IP,多网卡的情况)接收信息
    bzero(&(my_addr.sin_zero),8);//置字节字符串s的前n个字节为零。

    if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1)
    {
          perror("bind error!");
          exit(1);
    }
    else cout<<"bind success! "<<endl;

    if(listen(sockfd,10)==-1)///* 最大同时连接请求数 10*/
    {
        perror("listen error!");
        exit(1);
    }
    else cout<<"listening in port "<<port<<endl;

    while(1)
    {
        socklen_t sin_size = sizeof(struct sockaddr_in);
        cout<<"waiting for client..."<<endl;

        if((client_fd = accept(sockfd,(struct sockaddr*)&rem_addr,&sin_size))==-1)
        {
            perror("accept error!");
            exit(1);
        }
        cout<<"received a connection from "
        <<inet_ntoa(rem_addr.sin_addr) <<endl;

        if(!fork())/*子进程代码*/
        {

            char st[]="Hello,you are connected." ;
            //if(write(client_fd,st,strlen(st))==-1),equal exp
            if(send(client_fd,st,strlen(st),0)==-1)
            {
                perror("send error!");
                close(client_fd);
                exit(0);
            }
            else cout<<"sent successfully."<<endl;

            //receive info
            int revflag;
            char info[50];
            bzero(info,49);
            revflag=recv(client_fd,info,49,0);
            string str(info);
            if(revflag==-1)
                cout<<" receive error"<<endl;
            else cout<<"Receive info : "<<str<<endl;
            close(client_fd);
        }

    }
    return 0;
}


客户端     Client.cpp:

/***********************************************
向服务器3333端口(本程序中使用本机环回地址)发起TCP连接,
连接成功后先向发送消息,然后一直读取服务器发来的消息
***********************************************/
#include <iostream>
#include<stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>//inet_addr


using namespace std;

int main()
{
    int sockfd, serv_port=3333;
    struct sockaddr_in serv_addr;

    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        perror("socket error");
        exit(1);
    }

    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(serv_port);
    serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    bzero(&(serv_addr.sin_zero),8);//置字节字符串s的前n个字节为零。


    发起连接
    int conres=
    connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr));
    if(conres==-1)
    {
        cerr<<"connect error!"<<endl;
        exit(1);
    }

         //then send info to server
            char st[]="Hello,I'm from Client t3!" ;
            if(send(sockfd,st,strlen(st),0)==-1)
            {
                perror("send error!");
                close(sockfd);
                exit(0);
            }
            else cout<<"sent successfully."<<endl;

        int revflag=1;
       while(revflag!=-1)
       {

            char info[50];
            bzero(info,49);
            revflag=recv(sockfd,info,49,0);
            string str(info);
            if(revflag==-1)
                cout<<" receive error"<<endl;
            else cout<<"Receive info : "<<str<<endl;
       }
        close(sockfd);

    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值