xiaokufd 发表于 2019-3-27 20:38

【C】实作TCP socket(简易聊天软体)

本帖最后由 xiaokufd 于 2019-3-27 20:49 编辑

今天来讲讲何为TCP以及他的运作方式。首先,TCP是一种网路的传输方法,也是在各种传输方法当中比较稳定的一种。
那除了TCP之外还有其他种吗?有,还有一种协定叫做UDP,这种传输方式比TCP还来的快,但是他的封包遗失率较高,不稳定。
TCP采用三向握手(three-way handshake)建立连线来确保封包出现掉失的情况(如图)
https://s3.notfalse.net/wp-content/uploads/2016/12/24160012/Three-way-Handshake1.png

大概了解后,我们就用下图的这个TCP Socket流程图,来实作看看吧。
http://i.imgur.com/cqr4O2P.png
如果有不太懂的,可以上网查查或是留言问我。因为我是以大家有一定的基础来写这篇帖子的,所以可能没有讲的那么仔细。

这是Server的code
/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    char buffer;
    struct sockaddr_in serv_addr, cli_addr;
    int n;

    if (argc < 2) {
      printf(" usage %s port\n", argv);
      exit(1);
    }

    //Create Socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
       error(" create socket\n");
   
    //Initial socket
    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    //Binding
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
      error(" on binding\n");

    //Listening
    listen(sockfd,5);
   
    clilen = sizeof(cli_addr);
   
    //Accept
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0)
      error(" on accept\n");
    else
      printf("\n");

    //sending and receiving
    while(1){
      bzero(buffer,256);
      n = read(newsockfd,buffer,255);
      if (n < 0)
            error(" reading from socket\n");
      printf("%s", buffer);

      bzero(buffer,256);
      fgets(buffer,255,stdin);
      n = write(newsockfd,buffer,255);
      if (n < 0)
            error(" writing to socket\n");
    }

    //closing socket
    close(newsockfd);
    close(sockfd);
    return 0;
}


这是Client的code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    char buffer;

    if (argc < 3) {
       printf(" usage %s hostname port\n", argv);
       exit(0);
    }
    portno = atoi(argv);

    //Create socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
      error(" create socket");

    //Input ip
    server = gethostbyname(argv);
    if (server == NULL) {
      printf(" no such host\n");
      exit(0);
    }

    //Initial
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
    serv_addr.sin_port = htons(portno);

    //Connecting to server
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
      error(" connecting");
    else
      printf("\n");

    while(1){
      //for sending
      bzero(buffer,256);
      fgets(buffer,255,stdin);
      n = write(sockfd,buffer,strlen(buffer));
      if (n < 0)
             error("ERROR writing to socket");

      //for receiving
      bzero(buffer,256);
      n = read(sockfd,buffer,255);
      if (n < 0)
             error("ERROR reading from socket");
      printf("%s",buffer);
    }
    //socket closing
    close(sockfd);
    return 0;
}


执行结果

wffeeff 发表于 2019-3-27 21:42

可以帮我写个小程序吗?

xiaokufd 发表于 2019-3-27 21:59

wffeeff 发表于 2019-3-27 21:42
可以帮我写个小程序吗?

是什么样的程序呢?不知道的情况下我也不好回答哈哈。

wffeeff 发表于 2019-3-27 22:03

xiaokufd 发表于 2019-3-27 21:59
是什么样的程序呢?不知道的情况下我也不好回答哈哈。

写个DLL,即是服务端又是下载端,局域网传输文件用的。

xiaokufd 发表于 2019-3-28 18:52

wffeeff 发表于 2019-3-27 22:03
写个DLL,即是服务端又是下载端,局域网传输文件用的。

其實你要的需求,用我的這個Code都可以滿足。只是要小改一下。
至於把它寫成DLL,其實也蠻簡單的,上網google一下應該就會了
相信你可以做到的,如果寫的過程中有遇到其他問題,可以問我~~
或是真的寫不出來,我有空再幫你寫個吧。

wffeeff 发表于 2019-3-30 18:55

xiaokufd 发表于 2019-3-28 18:52
其實你要的需求,用我的這個Code都可以滿足。只是要小改一下。
至於把它寫成DLL,其實也蠻簡單的,上網g ...

厉害,其实我不懂C, 等大神有空帮搞个吧。可给红包
页: [1]
查看完整版本: 【C】实作TCP socket(简易聊天软体)