【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
是什么样的程序呢?不知道的情况下我也不好回答哈哈。
写个DLL,即是服务端又是下载端,局域网传输文件用的。 wffeeff 发表于 2019-3-27 22:03
写个DLL,即是服务端又是下载端,局域网传输文件用的。
其實你要的需求,用我的這個Code都可以滿足。只是要小改一下。
至於把它寫成DLL,其實也蠻簡單的,上網google一下應該就會了
相信你可以做到的,如果寫的過程中有遇到其他問題,可以問我~~
或是真的寫不出來,我有空再幫你寫個吧。 xiaokufd 发表于 2019-3-28 18:52
其實你要的需求,用我的這個Code都可以滿足。只是要小改一下。
至於把它寫成DLL,其實也蠻簡單的,上網g ...
厉害,其实我不懂C, 等大神有空帮搞个吧。可给红包
页:
[1]