linux网络编程备忘

本文详细介绍了网络编程中的关键步骤,包括socket初始化、设置非阻塞模式、端口复用、缓冲区大小调整等,并展示了如何配置TCP选项以提高性能,如关闭Nagle算法、设置SO_LINGER和SO_KEEPALIVE等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. 相关头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include <pthread.h>
#include <errno.h>
1.socket初始化
 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 if(s == -1) return -1;
 
 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if(s == -1) return -1;

struct sockaddr_in stAddr;
 memset(&stAddr, 0, sizeof(stAddr));
 stAddr.sin_family = AF_INET;
 stAddr.sin_addr.s_addr = inet_addr(pszIp);
 stAddr.sin_port = ntohs(ushPort);
 if(bind(s, (struct sockaddr*)&stAddr, sizeof(stAddr)) == -1)
 {
      return -2;
 }
 
2.非阻塞
 //set non-blocking
void setNonBlock( int sock_fd )
{
    int opts;
    opts = fcntl( sock_fd, F_GETFL );
    if( opts < 0 )
    {
        printf("err:fcntl F_GETFL");
        exit( 1 );
    }
    opts = opts | O_NONBLOCK ;
    if( fcntl( sock_fd, F_SETFL, opts ) < 0 )
    {
        printf("err:fcntl F_SETFL");
        exit( 1 );
    }
}

3.设置端口复用
使多个Socket对象绑定在同一个端口上
 //set socket port reuse
 if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)) == -1)
 {
      return -1;
 }

4.自定义各类缓冲大小
 //reset recv buf len
 if(setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&iRcvBufLen, sizeof(iRcvBufLen)) == -1)
 {
      return -1;
 }
 
//reset send buf len
 if(setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&iSendBufLen, sizeof(iSendBufLen)) == -1)
 {
      return -1;
 }
 
5.设置tcp nodelay( 关闭 Nagle算法 )
1) 在实时性要求较高时要关闭
2) Nagle算法用来减少少报文数目
         int flag = 1;
         int result = setsockopt(sock,            /* socket affected */
                                 IPPROTO_TCP,     /* set option at TCP level */
                                 TCP_NODELAY,     /* name of option */
                                 (char *) &flag,  /* the cast is historical
                                                         cruft */

                                 sizeof(int));    /* length of option value */
 
6.设置SO_LINGER
    将linger参数设为一个正整数n时(n的值最大是65,535),在调用close方法后,将最多被阻塞n秒。在这n秒内,系统将尽量将未送出的数据包发送出去;如果超过了n秒,如果还有未发送的数据包,这些数据包将全部被丢弃;而close方法会立即返回。如果将linger设为0,和关闭SO_LINGER选项的作用是一样的。
 
SO_LINGER选项用来改变此缺省设置。使用如下结构:
struct linger {
     int l_onoff; /* 0 = off, nozero = on */ 
     int l_linger; /* linger time */ 
}; 

struct linger so_linger;
so_linger.l_onoff = TRUE;
so_linger.l_linger = 30;
int result = setsockopt(s,
    SOL_SOCKET,
    SO_LINGER,
    &so_linger,
    sizeof so_linger);
 
7.设置SO_KEEPALIVE
    客户端Socket每隔段的时间(大约两个小时)就会利用空闲的连接向服务器发送一个数据包。这个数据包并没有其它的作用,只是为了检测一下服务器是否仍处于活动状态
keepAlive = 1; 
setsockopt(listenfd, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));
 
8.服务器初始化
    
listen_fd = socket( AF_INET, SOCK_STREAM, 0);

memset( &svrAddr, 0 , sizeof( sockaddr_in ) );
inet_aton( "127.0.0.1", &svrAddr.sin_addr );

svrAddr.sin_family = AF_INET;
svrAddr.sin_port = htons( 12345 );

int ret;
ret = bind( listen_fd, (sockaddr*)&svrAddr, sizeof( sockaddr_in ) );
if( ret != 0 )
{
    perror( "bind fail" );
    exit(-3);
}

listen( listen_fd, 20 );
 
9. Accept

//一定要初始化长度,否则很容易accept出错
clnLen = sizeof( sockaddr_in );
memset( &clnAddr, 0 , sizeof( sockaddr_in ) );

conn_fd = accept( listen_fd, (sockaddr*)&clnAddr, &clnLen );
if( conn_fd < 0 )
{
    perror("conn_fd < 0");
        break;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值