首页 > 代码库 > socket编程(一):简单回射C/S程序

socket编程(一):简单回射C/S程序

服务端代码:

//echoSvr.c

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define  ERR_EXIT(m)     do     {         perror(m);         exit(EXIT_FAILURE);     } while (0)

int main(void)
{
    //创建监听socket
    int listenfd;
    if ((listenfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) <0 )
        ERR_EXIT("socket");

    //绑定本地地址端口号
    struct sockaddr_in saServer;
    memset(&saServer, 0, sizeof(saServer));
    saServer.sin_addr.s_addr = inet_addr("127.0.0.1");
    saServer.sin_family = AF_INET;
    saServer.sin_port = htons(5188);

    if(bind( listenfd,(struct sockaddr*)&saServer, sizeof(saServer)) <0 )
        ERR_EXIT("bind");
    
    //监听
    if(listen(listenfd,SOMAXCONN) < 0)
        ERR_EXIT("listen");

    //接收客户端连接
    int conn;
    struct sockaddr_in saClient;
    socklen_t  saClientLen= sizeof(saClient);
    if((conn = accept(listenfd,(struct sockaddr* )&saClient,&saClientLen)) <0)
        ERR_EXIT("accept");

    //读取数据,打印出来,会送给客户端
    char recvBuf[1024];
    while(1)
    {
        memset(recvBuf,0,sizeof(recvBuf));
        int ret = read(conn,recvBuf,sizeof(recvBuf));
        fputs(recvBuf,stdout);
        write(conn,recvBuf,ret);
    }
    //关闭socket
    close(conn);
    close(listenfd);

    return 0;
}

客户端代码:

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

#define  ERR_EXIT(m)     do     {     perror(m);     exit(EXIT_FAILURE);     } while (0)

int main(void)
{
    int conn;
    if ((conn = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) <0 )
        ERR_EXIT("socket");

    struct sockaddr_in saServer;
    memset(&saServer, 0, sizeof(saServer));
    saServer.sin_addr.s_addr = inet_addr("127.0.0.1");
    saServer.sin_family = AF_INET;
    saServer.sin_port = htons(5188);

    if(connect(conn,(struct sockaddr*)&saServer,sizeof(saServer))<0)
        ERR_EXIT("socket");

    char recvBuf[1024];
    char sendBuf[1024];
    while(fgets(sendBuf,sizeof(sendBuf),stdin) != NULL)
    {
        write(conn,sendBuf,sizeof(sendBuf));
        read(conn,recvBuf,sizeof(recvBuf));
        fputs(recvBuf,stdout);
        memset(recvBuf,0,sizeof(recvBuf));
        memset(sendBuf,0,sizeof(sendBuf));    
    }
    close(conn);
    return 0;
}

makefile:

.PHONY:clean all
CC=gcc
CFLAGS=-Wall -g
BIN=echoSvr echoCli
all:$(BIN)
%.o:%.c
    $(CC) $(CFLAGS) -c $< -o $@
clean:
    rm -f *.o $(BIN)

环境:

gcc:4.6.3  ubuntu 12.04

程序缺陷:

1.服务器程序重启可能会出现地址绑定错误

原因:程序刚关闭  ip地址处理TIME_WAIT状态

解决方案:一般最好在绑定地址前用时setsockopt函数设置REUSEADDR选项,代码如下

int on = 1;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
        ERR_EXIT("setsockopt");

2.本程序只能对一个客户端连接,下一节解决这个问题。