c语言网络编程socket源码_socket c语言编程

hacker|
121

文章目录:

socket编程。怎么实现数据包的转发?C语言版的。

我也不知道····只好复制一份···共同学习~~ 要写网络程序就必须用Socket,这是程序员都知道的。而且,面试的时候,我们也会问对方会不会Socket编程?一般来说,很多人都会说,Socket编程基本就是listen,accept以及send,write等几个基本的操作。是的,就跟常见的文件操作一样,只要写过就一定知道。对于网络编程,我们也言必称TCP/IP,似乎其它网络协议已经不存在了。对于TCP/IP,我们还知道TCP和UDP,前者可以保证数据的正确和可靠性,后者则允许数据丢失。最后,我们还知道,在建立连接前,必须知道对方的IP地址和端口号。除此,普通的程序员就不会知道太多了,很多时候这些知识已经够用了。最多,写服务程序的时候,会使用多线程来处理并发访问。我们还知道如下几个事实:1。一个指定的端口号不能被多个程序共用。比如,如果IIS占用了80端口,那么Apache就不能也用80端口了。2。很多防火墙只允许特定目标端口的数据包通过。3。服务程序在listen某个端口并accept某个连接请求后,会生成一个新的socket来对该请求进行处理。于是,一个困惑了我很久的问题就产生了。如果一个socket创建后并与80端口绑定后,是否就意味着该socket占用了80端口呢?如果是这样的,那么当其accept一个请求后,生成的新的socket到底使用的是什么端口呢(我一直以为系统会默认给其分配一个空闲的端口号)?如果是一个空闲的端口,那一定不是80端口了,于是以后的TCP数据包的目标端口就不是80了--防火墙一定会组织其通过的!实际上,我们可以看到,防火墙并没有阻止这样的连接,而且这是最常见的连接请求和处理方式。我的不解就是,为什么防火墙没有阻止这样的连接?它是如何判定那条连接是因为connet80端口而生成的?是不是TCP数据包里有什么特别的标志?或者防火墙记住了什么东西?后来,我又仔细研读了TCP/IP的协议栈的原理,对很多概念有了更深刻的认识。比如,在TCP和UDP同属于传输层,共同架设在IP层(网络层)之上。而IP层主要负责的是在节点之间(End to End)的数据包传送,这里的节点是一台网络设备,比如计算机。因为IP层只负责把数据送到节点,而不能区分上面的不同应用,所以TCP和UDP协议在其基础上加入了端口的信息,端口于是标识的是一个节点上的一个应用。除了增加端口信息,UPD协议基本就没有对IP层的数据进行任何的处理了。而TCP协议还加入了更加复杂的传输控制,比如滑动的数据发送窗口(Slice Window),以及接收确认和重发机制,以达到数据的可靠传送。不管应用层看到的是怎样一个稳定的TCP数据流,下面传送的都是一个个的IP数据包,需要由TCP协议来进行数据重组。所以,我有理由怀疑,防火墙并没有足够的信息判断TCP数据包的更多信息,除了IP地址和端口号。而且,我们也看到,所谓的端口,是为了区分不同的应用的,以在不同的IP包来到的时候能够正确转发。TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。就像操作系统会提供标准的编程接口,比如Win32编程接口一样,TCP/IP也必须对外提供编程接口,这就是Socket编程接口--原来是这么回事啊!在Socket编程接口里,设计者提出了一个很重要的概念,那就是socket。这个socket跟文件句柄很相似,实际上在BSD系统里就是跟文件句柄一样存放在一样的进程句柄表里。这个socket其实是一个序号,表示其在句柄表中的位置。这一点,我们已经见过很多了,比如文件句柄,窗口句柄等等。这些句柄,其实是代表了系统中的某些特定的对象,用于在各种函数中作为参数传入,以对特定的对象进行操作--这其实是C语言的问题,在C++语言里,这个句柄其实就是this指针,实际就是对象指针啦。现在我们知道,socket跟TCP/IP并没有必然的联系。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以,socket的出现只是可以更方便的使用TCP/IP协议栈而已,其对TCP/IP进行了抽象,形成了几个最基本的函数接口。比如create,listen,accept,connect,read和write等等。现在我们明白,如果一个程序创建了

socket,linux用c语言实现

哦字符串回显啊unix网络编程有好几个版本,你可以去网上下它的源代码(百度搜UNIX网络编程 源代码),呃大部分被我的改的不成样了,发个能用的给看看吧

//server

#includestdio.h

#includesys/socket.h

#includearpa/inet.h

#includenetinet/in.h

#includestdlib.h

#includestring.h

#includeunistd.h

#includeerrno.h

#includesignal.h

#define SERVPORT 1956

#define MAXLINE 100

typedef void Sigfunc(int);

void sig_chld(int signo)

{

        pid_t pid;

        int stat;

        while( (pid = waitpid(-1, stat, WNOHANG))  0)

                printf("child %d terminated\n", pid);

        return;

}

//read data from client, and write back to them

void str_echo(int sockfd)

{

        ssize_t n;

        char buf[MAXLINE];

        again:

        while( (n = read(sockfd, buf, MAXLINE))  0 )

                write(sockfd, buf, n);

        if(n  0  errno ==EINTR)

                goto again;

        else if(n  0 )

                printf("error\n");

}

int main(int argc, char** argv)

{

        int listenfd, connfd;

        socklen_t clilen;

        pid_t childpid;

        struct sockaddr_in servaddr, cliaddr;

        if( (listenfd = socket(AF_INET, SOCK_STREAM, 0))  0 )

        {

                printf("socket fd error\n");

                return -1;

        }

        bzero(servaddr, sizeof(servaddr));

        servaddr.sin_family = AF_INET;

        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

        servaddr.sin_port = htons(SERVPORT);

        if( bind(listenfd, (struct sockaddr *)servaddr, sizeof(servaddr)) 0 )

        {

                printf("bind error\n");

                return -1;

        }

        int backlong = 0;

        if(listen(listenfd, backlong) 0 )

        {

                printf("listen error\n");

                return -1;

        }

        signal(SIGCHLD, sig_chld);

        for(;;)

        {

                clilen = sizeof(cliaddr);

                if( (connfd = accept(listenfd, (struct sockaddr *)cliaddr, clilen))  0)

                {

                        if(errno == EINTR)      continue;

                        else printf("accept error\n");

                        return 0;

                }

                printf("accept \n");

                if( (childpid = fork()) == 0 )

                {

                        close(listenfd);    //close child's listen socket

                        str_echo(connfd);

                        exit(0);

                }

                close(connfd);

        }

 }

//client

#includestdio.h

#includesys/socket.h

#include arpa/inet.h

#include netinet/in.h

#include stdlib.h

#include string.h

#define MAXLINE 10

int main(int argc, char ** argv)

{

        int sockfd, n;

        char recvline[MAXLINE+1];

        struct sockaddr_in servaddr,binaddr;

        if(argc != 2)

        {

                printf("usage: IPADDRESS\n");

                return -1;

        }

        if( (sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))  0)

        {

                printf("socket error\n");

                return -1;

        }

        bzero(servaddr, sizeof(servaddr));

        servaddr.sin_family = AF_INET;

        servaddr.sin_port = htons(15);

        if(inet_pton(AF_INET, argv[1], servaddr.sin_addr)=0 )    

        {

                printf("inet_pton error for s \n", argv[1]);

                return -1;

        }

        int bindSock;

        binaddr.sin_family = AF_INET;

        inet_pton(AF_INET, "222.26.224.56", binaddr.sin_addr);

        binaddr.sin_port = htons(20000);

        int reuse0 = 1;

        if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)reuse0, sizeof(reuse0)) == -1)

        {

                printf("set socket error\n");

                return -1;

        }

        if( bind(sockfd, (struct sockaddr *)binaddr, sizeof(servaddr)) 0 )

        {

                printf("bind error\n");

                return -1;

        }

        if( connect(sockfd, (struct sockaddr*) servaddr, sizeof(servaddr) )  0 )

        {

                printf("connection refuse\n");

                return -1;

        }

        while( (n = read(sockfd, recvline, MAXLINE))  0 )

        {

                recvline[n] = 0;

                if(fputs(recvline, stdout) == EOF)

                {

                        printf("fputs error");

                        return -1;

                }

                printf("\n");

        }

        if(n  0 )

        {

                printf("read error");

                return -1;

        }

}

在windows下,如何用纯C语言实现socket网络编程?

mfc只是对socket进行了一些封装,大部分人做网络编程都是用的原始的socket,比如如下接口都可以在c下进行调用

1.socket()

2.bind()

3.connect()

4.listen()

5.accept()

6.send() 和recv()

7.sendto() 和recvfrom()

8.close() 和shutdown()

9.getpeername()

10.gethostname()

这些接口是在Winsock2.h中定义的不是在mfc中定义的,你只需要包含Winsock2.h头文件和Ws2_32.lib库就可以了。

怎样用C语言做socket网络编程?

mfc只是对socket进行了一些封装,大部分人做网络编程都是用的原始的socket,比如如下接口都可以在c下进行调用

1.socket()

2.bind()

3.connect()

4.listen()

5.accept()

6.send() 和recv()

7.sendto() 和recvfrom()

8.close() 和shutdown()

9.getpeername()

10.gethostname()

这些接口是在Winsock2.h中定义的不是在mfc中定义的,你只需要包含Winsock2.h头文件和Ws2_32.lib库就可以了。

在windows下用C语言如何实现socket网络编程,需要用到哪些头文件或者库?

需要用到的头文件包含:

#include winsock2.h

#include windows.h

与Linux环境下socket编程相比,windows环境多了一个步骤:启动或者初始化winsock库

Winsock,一种标准API,一种网络编程接口,用于两个或多个应用程序(或进程)之间通过网络进行数据通信。具有两个版本:

Winsock 1:

Windows CE平台支持。

头文件:WinSock.h

库:wsock32.lib

Winsock 2:

部分平台如Windows CE貌似不支持。通过前缀WSA可以区别于Winsock 1版本。个别函数如WSAStartup、WSACleanup、WSARecvEx、WSAGetLastError都属于Winsock 1.1规范的函数;

头文件:WinSock2.h

库:ws2_32.lib

mswsock.h用于编程扩展,使用时必须链接mswsock.dll

扩展资料

winsock库的加载与卸载:

加载:int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);

加载成功,返回值为0。

WORD wVersionRequested:加载的winsock版本,使用宏MAKEWORD(x, y),x表示高字节,y表示低字节。然而使用时MAKEWORD(2, 2)。高字节与低字节相同~~

LPWSADATA lpWSAData:WSADATA结构的指针,传入参数后,系统帮助我们填充版本信息。有兴趣的可以看看结构体内容,不过基本用不着。

卸载:int WSACleanup(void);比起加载,卸载的函数真是轻松愉快。

关于c语言的socket网络编程

sender

没有看到

i

打印,是由于你没有加换行,由于标准输出是行缓冲,所以不会马上打印,而是要等遇到

\n

或者进程结束才会打印。你可以写成

printf("%d\n");

就能看到发送方的打印。

接收方也可以加上printf来打印。

这么简单的程序,用gdb自己调试也可以。

5条大神的评论

  • avatar
    访客 2022-08-28 上午 06:33:38

    o again;        else if(n  0 )                printf("error\n");}int main(int argc, char** argv){        int listen

  • avatar
    访客 2022-08-28 上午 10:24:26

    了一个很重要的概念,那就是socket。这个socket跟文件句柄很相似,实际上在BSD系统里就是跟文件句柄一样存放在一样的进程句柄表里。这个socket其实是一个序号,表示其在句柄表中的位置。这一点,我们已经见过很多了,比如文件句柄,窗口句柄等等。这些句柄,其实

  • avatar
    访客 2022-08-28 上午 09:41:25

    t(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)reuse0, sizeof(reuse0)) == -1)        {                print

  • avatar
    访客 2022-08-28 下午 02:30:11

      {                        if(errno == EINTR)      continue;                        else printf("accept er

  • avatar
    访客 2022-08-28 上午 08:24:53

     (sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))  0)        {                printf("socket error\n");                return -1;        }    

发表评论