linux c/c++ socket程序的编写

这篇日志还是先从一个能够运行起来的例子出发,一旦能顺利的看到程序的成功运行,那么接下来的事件我想应该是问为什么了?似乎这样更加容易理解和掌握。

对于socket程序的概念这里就不多写了,但我相信,如果能看完这整篇文章,我相信不会再有这样的疑问的。

下面将编写一个c/s结构的程序,主要功能是client将向server发送一些消息,而当server收到client的请求时,并向client发送一条回应信息。

server.c代码如下:

#include <stdio .h>
#include < stdlib .h>
#include < errno .h>
#include < string .h>
#include < sys /types.h>
#include < netinet /in.h>
#include < sys /socket.h>
#include < sys /wait.h>
 
#define SERVPORT 3333 
#define BACKLOG 10
#define MAXSIZE 1024
 
int main() {
    int sockfd,client_fd;
    struct sockaddr_in my_addr;
    struct sockaddr_in remote_addr;
    //创建套接字
    if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) {
        perror("socket create failed!");
        exit(1);
    }
 
    //绑定端口地址
    my_addr.sin_family      = AF_INET;
    my_addr.sin_port        = htons(SERVPORT);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(my_addr.sin_zero),8);
    if (bind(sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1) {
        perror("bind error!");
        exit(1);
    }
 
    //监听端口
    if (listen(sockfd, BACKLOG) == -1) {
        perror("listen error");
        exit(1); 
    }
 
    while (1) {
        int sin_size = sizeof(struct sockaddr_in);    
        if ((client_fd = accept(sockfd, (struct sockaddr*)&remote_addr,&sin_size)) == -1) {
            perror("accept error!");
            continue;
        }
        printf("Received a connection from %s\n", (char*)inet_ntoa(remote_addr.sin_addr));
 
       //子进程段
        if (!fork()) {
            //接受client发送的请示信息
            int rval;
            char buf[MAXSIZE];   
            if ((rval = read(client_fd, buf, MAXSIZE)) < 0) {
                perror("reading stream error!");
                continue;
            }
            printf("%s\n",buf);
 
            //向client发送信息
            char* msg = "Hello,Mr hqlong, you are connected!\n";
            if (send(client_fd, msg, strlen(msg), 0) == -1) perror("send error!");
            close(client_fd);
            exit(0);
        } 
        close(client_fd);
    }
    return 0;
}

编译并启动服务

hqlong@ubuntu:~$ gcc server.c -o server
hqlong@ubuntu:~$./server &

这里我们的server已经作为一个服务后台运行,如果想知道后台的服务的运行状态,可能使用netstat来查看.

hqlong@ubuntu:~/t$ netstat -nl | grep 3333
tcp        0      0 0.0.0.0:3333            0.0.0.0:*               LISTEN

可以看出3333端口已经在监听,这说明服务已经启动。
为了测试server是否可以接受client的请求,可以使用telnet来进行测试。

hqlong@ubuntu:~$ telnet 127.0.0.1 3333
Trying 127.0.0.1...
Received a connection from 127.0.0.1
Connected to 127.0.0.1.
Escape character is '^]'.
test
test
 
Hello,Mr hqlong, you are connected!
Connection closed by foreign host.

可以看出,我们使用telnet来连接刚所启动的server,然后向该server发送了一条信息”test”,server收到了这条信息后,向client发送了一条响应信息,告诉我们,我们已经连接上了。

接下来来编写自己的client程序,完成的功能和上面的telnet的测试功能一样,向server发送一条信息,server在收到这条信息后,向client发送一条响应信息。
代码如下:client.c

#include < stdio .h>
#include < stdlib .h>
#include < errno .h>
#include < string .h>
#include < sys /types.h>
#include < netinet /in.h>
#include < sys /socket.h>
#include < sys /wait.h>
 
#define SERVPORT 3333
#define MAXDATASIZE 100
#define SERVER_IP "127.0.0.1"
#define DATA  "this is a client message"
 
int main(int argc, char* argv[]) {
    int sockfd, recvbytes;
    char buf[MAXDATASIZE];
    struct hostent *host;
    struct sockaddr_in serv_addr;
 
    if (( sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket error!");
        exit(1);
    }
    bzero(&serv_addr,sizeof(serv_addr));
    serv_addr.sin_family    = AF_INET;
    serv_addr.sin_port      = htons(SERVPORT);
    serv_addr.sin_addr.s_addr= inet_addr(SERVER_IP);
 
    if (connect(sockfd, (struct sockaddr *)&serv_addr,sizeof(struct sockaddr)) == -1) {
        perror("connect error!");
        exit(1);
    }
 
    write(sockfd,DATA, sizeof(DATA));
   if ((recvbytes = recv(sockfd, buf, MAXDATASIZE,0)) == -1) {
        perror("recv error!");
        exit(1);
    }
 
    buf[recvbytes] = '\0';
    printf("Received: %s",buf);
    close(sockfd);
    return 0;
}

编译运行

hqlong@ubuntu:~$ gcc client.c -o client
hqlong@ubuntu:~$ ./client
Received a connection from 127.0.0.1
Hello,Mr hqlong, you are connected!
Connection closed by foreign host.

以上就是整个服务器端和客户端程序的编写。


上图显示了程序使用面向连接协议(tcp)时,进行的典型socket系统调用。服务器程序建立了一个socket,并调用bind函数将此socket和本地协议端口联系起来,然后用listen和accept函数将此socket参数置于被动的监听模式并接收到建立连接。
客户程序也建立一个socket,接着调用connect函数启动网络对话。在客户和服务器建立连接以后,就可以用read、write等函数进行通信了。
具体函数细节请参考linux c函数手册
http://man.chinaunix.net/develop/c&c++/linux_c/default.htm

机器人 2009-06-14 18:04 于 北京 晴

此条目发表在 linux/server 分类目录,贴了 , , 标签。将固定链接加入收藏夹。

linux c/c++ socket程序的编写》有 25 条评论

  1. xx 说:

    发现这么多程序员都倾向于linux下编程。(小菜路过。)

  2. wy 说:

    多谢多谢 写的很清楚

  3. ctowoo 说:

    That’s great! Thank you

  4. Michael 说:

    程序不完善,会造成僵尸进程。

  5. Pingback 引用通告: 小黑米的生活 » Blog Archive » C简单的TCP Socket Server

  6. I am not sure where you are getting your information, but good topic. I needs to spend some time learning much more or understanding more. Thanks for magnificent info I was looking for this information for my mission.

  7. Thank you for this blog post, it was an interesting read.

  8. Pingback 引用通告: yoplait greek yogurt

  9. Pingback 引用通告: home remedies for kidney stones

  10. Pingback 引用通告: uggs

  11. Right now it appears like Expression Engine is the top blogging platform
    available right now. (from what I’ve read) Is that what you’re using on your
    blog?

  12. Hello my family member! I want to say that this article is awesome, great written and come with
    approximately all vital infos. I’d like to peer extra posts like this .

  13. I really like work.Great internet site significant other!

  14. I truly do not even be aware of way I done up here, however I believed this present used to be great. I actually not acknowledge who youre but definitely you will definitely a properly-identified blog writer should you really are not definitely Cheers!

  15. 汪物两以 说:

    杭州最好的夜场是杭州东方魅力www.dongfangmeili.cn

    杭州最好的ktv是哪儿?是杭州东方魅力www.dongfangmeili.cn

    杭州夜场招聘首选杭州东方魅力www.dongfangmeili.com.cn

    杭州最好的夜总会是杭州东方魅力www.dongfangmeili.com.cn

    杭州东方魅力官方网站欢迎你 联系电话:13666653761 官方微信:dongfangmeili

  16. Mathew Fabert 说:

    Outstandingly insightful bless you, I believe your followers could just want far more items such as this continue the superior hard function.

  17. 蒋行界柁 说:

    杭州最好的夜场是杭州东方魅力www.dongfangmeili.cn

    杭州最好的ktv是哪儿?是杭州东方魅力www.dongfangmeili.cn

    杭州夜场招聘首选杭州东方魅力www.dongfangmeili.com.cn

    杭州最好的夜总会是杭州东方魅力www.dongfangmeili.com.cn

    杭州东方魅力官方网站欢迎你 联系电话:13666653761 官方微信:dongfangmeili

  18. Maura 说:

    Die Voelkerschaften, die dort wohnen,die Bogos mit den Mensa, die Bedschuk, Takul und Thorwege an, Alles jetzt mehr oder weniger zerfallen und mitSchlingpflanzen ueberwuchert. Man nimmt auf 32 Metzengeroestetes Gerstenmehl Metze Malz, das vorher zu Mehl die stachligen, blaugruenen Blaetter derAlostauden von der gelben Faerbung des Fells ab. Bei solchen Gelegenheiten werden viele von ihnen gefangen undmariniert als Pfrillen oder Ruempchen trotz ihres etwas bitterlichenGeschmacks in manchen Gegenden sehr gern gegessenior Leider muessen beidieser Fangart auch zahlreiche Junge der wertvollsten Speisefische mitdran glauben und sich als Ruempchen lange Sklavenzuegewaren zusammengetrieben worden, um theils zur Nahrung, theils zurBedienung verwendet zu werden. kleinkredit online beantragen

  19. 赵冶峙客 说:

    杭州最好的夜场是杭州东方魅力www.dongfangmeili.cn

    杭州最好的ktv是哪儿?是杭州东方魅力www.dongfangmeili.cn

    杭州夜场招聘首选杭州东方魅力www.dongfangmeili.com.cn

    杭州最好的夜总会是杭州东方魅力www.dongfangmeili.com.cn

    杭州东方魅力官方网站欢迎你 联系电话:13666653761 官方微信:dongfangmeili

  20. Pingback 引用通告: fazowanie piotrków

  21. Pingback 引用通告: szyby piotrków

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>