面向连接的套接字实例[Windows平台]

服务器端代码:
#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

#define PROTOPORT    5188    //监听套接字的缺省协议的端口号
#define QLEN    6               //监听套接字的请求队列大小
int visit = 0;                     //对于客户机连接的技数
void main(int argc, char** argv)
{
    WSADATA wsa;            // added for windows

    struct hostent *ptrh;    // not used 指向主机列表中的一个条目的指针
    struct sockaddr_in servaddr;     //存放服务器网络地址的结构
    struct sockaddr_in clientaddr;     //存放客户端网络地址的结构
    int listenfd;                    // 监听套接字描述符
    int clientfd;                    //响应套接字描述符
    unsigned short port;
    int alen;
    char buf[1000];
   
    // added for windows
    if(WSAStartup(MAKEWORD(2, 2), &wsa) != 0){     //对Winsock进行初始化!
        fprintf(stderr, "winsock2 initiation failed/n");
        exit(1);
    }

    memset((char *)&servaddr, 0, sizeof(servaddr));        // 清空sockaddr结构
    servaddr.sin_family = AF_INET;                   //设置为Internet协议族
    servaddr.sin_addr.s_addr = INADDR_ANY;            //设置本地IP地址

    if(argc > 1){
        port = atoi(argv[1]);
    }
    else{
        port = PROTOPORT;
    }

    if(port > 0){                                   //测试端口号是否合法
        servaddr.sin_port = htons(port);
    }
    else{
        fprintf(stderr, "bad port number %s/n", argv[1]);   //答应错误信息并退出
        exit(1);
    }

    listenfd = socket(AF_INET, SOCK_STREAM, 0);//创建一个用于监听的流式接字
    if(listenfd < 0){
        fprintf(stderr, "socket creation failed/n");
        exit(1);
    }

    if(bind(listenfd, (sockaddr *)&servaddr, sizeof(servaddr)) < 0){
        fprintf(stderr, "bind failed/n");//将本地地址绑定到监听套接字
        exit(1);
    }

    if(listen(listenfd, QLEN) < 0){//开始监听套接字请求队列长度
        fprintf(stderr, "listen failed/n");
        exit(1);
    }

    while(1){//服务器主循环——处理来自客户机断的连接请求
        alen = sizeof(clientaddr);//接受请求并生成套接字
        if((clientfd = accept(listenfd, (struct sockaddr *)&clientaddr, &alen)) < 0){
            fprintf(stderr, "accept failed/n");
            exit(1);
        }
        visit++;
        sprintf(buf, "this server has been contacted %d time/n", visit);
        send(clientfd, buf, strlen(buf), 0);
        closesocket(clientfd);//关闭响应
    }
    WSACleanup();
}
客户端代码:
#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

#define PROTOPORT    5188
extern int errno;
char localhost[] = "localhost";

void main(int argc, char** argv)
{
    WSADATA wsa;

    struct hostent *ptrh;
    struct sockaddr_in servaddr;
    int sockfd;//客户端的套接字描述符
    unsigned short port;
    char *host;
    int n;//读取字符数
    char buf[1000];//缓冲区,接收服务器发来的数据

    // added for windows
    if(WSAStartup(MAKEWORD(2, 2), &wsa) != 0){
        fprintf(stderr, "winsock2 initiation failed/n");
        exit(1);
    }

    memset((char *)&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;

    if(argc > 2){
        port = atoi(argv[2]);//如果定义了协议端口号,就转换成整数
    }
    else{
        port = PROTOPORT;
    }

    if(port > 0){//若端口号合法就将他装入网络地址结构
        servaddr.sin_port = htons(port);
    }
    else{
        fprintf(stderr, "bad port number %s/n", argv[2]);
        exit(1);
    }

    if(argc > 1){
        host = argv[1];//如果指定了主机参数,就使用它
    }
    else{
        host = localhost;
    }
//将主机名转换成IP地址存于servddr中
    ptrh = gethostbyname(host);//获取IP地址
    if((char *)ptrh == NULL){//检查主机名是否有效
        fprintf(stderr, "invalid host: %s/n", host);
        exit(1);
    }

    memcpy(&servaddr.sin_addr, ptrh->h_addr, ptrh->h_length);
//创建一个套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0){
        fprintf(stderr, "socket creation failed/n");
        exit(1);
    }
//请求连接到服务器
    if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
        fprintf(stderr, "connection failed/n");
        exit(1);
    }
//从套接字反复读取数据,并输出到屏幕上
    n = recv(sockfd, buf, sizeof(buf), 0);
    while(n > 0){
        buf[n] = 0;
        fprintf(stdout, buf);
        n = recv(sockfd, buf, sizeof(buf), 0);
    }

    closesocket(sockfd);//关闭套接字
    WSACleanup();//注销,释放资源
    exit(0);//终止客户程序
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值