socket改-面向連接并發(fā)

getservbyname()
將一些服務(wù)名轉(zhuǎn)換為熟知的端口號(hào)
如HTTP:80

gethostbyname()
域名解析將域名轉(zhuǎn)換稱為ip

getprotobyname()
協(xié)議號(hào)的解析

對(duì)于dev c++
分開的代碼編譯不了。
https://blog.csdn.net/qq_31869107/article/details/81234785

設(shè)計(jì)一個(gè)connectsock過程封裝底層代碼

//consock.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock.h>

#ifdef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif          //寫不寫都一樣winsock.h里有完成的。

void errexit(const char *, ...);   //異常退出函數(shù)

SOCKET connectsock(const char * host, const char * service,
                     const char * transport)
{
    struct hostent * phe;   //域名解析將域名解析成ip的返回地址
    struct servent * pse;   //常用端口號(hào)函數(shù)返回值 存放
    struct protoent * ppe;  //協(xié)議號(hào)
    struct sockaddr_in sin; //目標(biāo)地址
    int s, type;            //描述符(windows 叫句柄)和傳輸類型(UDP/TCP)
    
    memset(&sin, 0, sizeof(sin));   //清0
    sin.sin_family = AF_INET;       //IPv4

    if (pse = getservbyname(service, transport))  //獲取服務(wù)端口號(hào)
        sin.sin_port = pse->s_port;
    else if((sin.sin_port = htons((u_short)atoi(service))) == 0)  //如果是端口泻拦,htons轉(zhuǎn)化成網(wǎng)絡(luò)字節(jié)
        errexit("can't get %s service entry\n", service);   //都不是報(bào)錯(cuò)退出
    
    if (phe = gethostbyname(host))  //獲取域名ip
        memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);  //復(fù)制phe的lengh長(zhǎng)度到sin
    else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) //如果是ip地址 inet_addr十進(jìn)制的數(shù)轉(zhuǎn)化為二進(jìn)制的數(shù)
        errexit("can't get %s host entry\n", host);
    
    if ((ppe = getprotobyname(transport)) == 0) //協(xié)議號(hào)
        errexit("can't get %s protocol entry\n", transport);

    if (strcmp(transport, "udp") == 0)  
        type = SOCK_DGRAM;
    else
        type = SOCK_STREAM;
    
    s = socket(PF_INET, type, ppe->p_proto); //創(chuàng)建套接字
    if (s == INVALID_SOCKET)
        errexit("can't create socket:%d\n", GetLastError());
    
    if (connect(s, (SOCKADDR *)&sin, sizeof(sin)) == SOCKET_ERROR) //連接服務(wù)器
        errexit("can't connect to %s.%s:%d\n", host, service, GetLastError());
    
    return s;
}

connectTCP過程

//conTCP.cpp
#include <winsock.h>
SOCKET connectsock(const char *, const char *, const char *);

SOCKET connectTCP(const char * host , const char * service)
{
    return connectsock(host, service, "tcp");
}

異常處理

//errexit.cpp
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>

void errexit(const char * format, ...)
{
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    WSACleanup();
    exit(1);
}

客戶端主函數(shù)

//TCPdtc.cpp
#include <stdlib.h>
#include <stdio.h>
#include <winsock.h>

void TCPdaytime(const char *, const char *);
void errexit(const char *, ...);
SOCKET connectTCP(const char *, const char *);

#define LINELEN 128
#define WSVERS MAKEWORD(2, 0)

int main(int argc, char const *argv[])
{
    const char *host = "localhost";   //目標(biāo)
    const char *service = "daytime";    //服務(wù)
    WSADATA wsadata;
    switch (argc)
    {
    case 1:
        host = "localhost";
        break;
    case 3:
        service = argv[2];
    case 2:
        host = argv[1];
        break;
    default:
        fprintf(stderr, "usage: TCPdaytime");
        exit(1);
    }
    if (WSAStartup(WSVERS, &wsadata) != 0)      //初始化
        errexit("WSASTARTUP, FAILED\n");
    TCPdaytime(host, service);
    WSACleanup();

    return 0;
}

void TCPdaytime(const char * host, const char * service)
{
    char buf[LINELEN + 1];
    SOCKET s;
    int cc;
    s = connectTCP(host, service);

    cc = recv(s, buf, LINELEN, 0);
    while (cc != SOCKET_ERROR && cc > 0)  //tcp是一點(diǎn)一點(diǎn)傳輸?shù)倪^來的不是完整的包所以要循環(huán)
    {
        buf[cc] = '\0';
        (void)fputs(buf, stdout);
        cc = recv(s, buf, LINELEN, 0);
    }
    closesocket(s);
}

服務(wù)器端

//passsock.cpp
#include <stdlib.h>
#include <string.h>
#include <winsock.h>
void errexit(const char * , ...);

SOCKET passivesock(const char * service, const char * transport, int qlen)
{
    struct servent * pse;
    struct protoent * ppe;
    struct sockaddr_in sin;
    SOCKET s;
    int type;

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;

    if (pse = getservbyname(service, transport))
        sin.sin_port = (u_short)pse->s_port;
    else if((sin.sin_port = htons((u_short)atoi(service))) == 0)
        errexit("can't get %s\n", service);
    
    if ((ppe = getprotobyname(transport)) == 0)
        errexit("can't get %s", transport);
    
    if (strcmp(transport, "udp") == 0)
        type = SOCK_DGRAM;
    else 
        type = SOCK_STREAM;
    
    s = socket(PF_INET, type, ppe->p_proto);
    if (s == INVALID_SOCKET)
        errexit("can't create socket:%d\n",GetLastError());

    if (bind(s, (SOCKADDR *)&sin, sizeof(sin)) == SOCKET_ERROR)
        errexit("can't bind %s port, %d", service, GetLastError());
    if(type == SOCK_STREAM && listen(s, qlen) == SOCKET_ERROR)
        errexit("can't listen on %s port:%d", service, GetLastError());
        
    return s;
}
//passiveTCP.cpp
#include <winsock.h>

SOCKET passivesock(const char *, const char *, int);

SOCKET passiveTCP(const char * service, int qlen)
{
    return passivesock(service, "tcp", qlen);
}

主程序


#include <stdlib.h>
#include <winsock.h>
#include <process.h>
#include <time.h>

void errexit(const char *, ...);
void TCPdaytimed(SOCKET);
SOCKET passiveTCP(const char *, int);

#define QLEN 5
#define WSVERS MAKEWORD(2, 0)

void main(int argc, char *argv[])
{
    struct sockaddr_in fsin;
    char *service = "daytime";
    SOCKET msock, ssock;
    int alen;
    WSADATA wsadata;

    switch (argc)
    {
    case 1:
        /* code */
        break;
    case 2:
        service = argv[1];
    default:
        errexit("usage:TCPDAYTIMED\n");

    }
    if (WSAStartup(WSVERS, &wsadata) != 0)
        errexit("failed\n");
    msock = passiveTCP(service, QLEN);
    while (1)
    {
        alen = sizeof(SOCKADDR);
        ssock = accept(msock, (SOCKADDR *)&fsin, &alen);
        if (ssock == INVALID_SOCKET)
            errexit("accept %d", GetLastError());
        if (_beginthread((void(*)(void *))TCPdaytimed, 0,
            (void *)ssock) < 0)
        {
            errexit("_beg%s", strerror(errno));
        }
        
    }
        
}

void TCPdaytimed(SOCKET fd)
{
    char * pts;
    time_t now;

    (void)time(&now);
    pts = ctime(&now);
    (void)send(fd, pts, strlen(pts), 0);
    (void)closesocket(fd);
}

出自 : 計(jì)算機(jī)網(wǎng)絡(luò)之網(wǎng)盡其用
https://www.icourse163.org/learn/HIT-154005?tid=1206679208#/learn/announce

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末进倍,一起剝皮案震驚了整個(gè)濱河市钦椭,隨后出現(xiàn)的幾起案子瞒津,更是在濱河造成了極大的恐慌袜匿,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舒憾,死亡現(xiàn)場(chǎng)離奇詭異镀钓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)镀迂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門丁溅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人探遵,你說我怎么就攤上這事窟赏。” “怎么了别凤?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵饰序,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我规哪,道長(zhǎng)求豫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任诉稍,我火速辦了婚禮蝠嘉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘杯巨。我一直安慰自己蚤告,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布服爷。 她就那樣靜靜地躺著杜恰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仍源。 梳的紋絲不亂的頭發(fā)上心褐,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音笼踩,去河邊找鬼逗爹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嚎于,可吹牛的內(nèi)容都是我干的掘而。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼于购,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼袍睡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起肋僧,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤女蜈,失蹤者是張志新(化名)和其女友劉穎持舆,沒想到半個(gè)月后色瘩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伪窖,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年居兆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了覆山。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泥栖,死狀恐怖簇宽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吧享,我是刑警寧澤魏割,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站钢颂,受9級(jí)特大地震影響钞它,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜殊鞭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一遭垛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧操灿,春花似錦锯仪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至救鲤,卻和暖如春久窟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜒简。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工瘸羡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搓茬。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓犹赖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親卷仑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子峻村,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容