TCP server程式設計

2021-08-03 02:07:52 字數 4682 閱讀 8829

一、基本解釋 

在之前的部落格中我已經簡單的介紹過tcp建立連線時的三次握手,以及在斷開連線時的四次揮手,在此我就不再多說了,此次介紹基於tcp的套接字程式設計。在此類程式設計中會用到一些結構體以及函式,下來我簡單地介紹下這些:

1.struct sockaddr_in

其結構如下

sockaddr_in(在netinet/in.h中定義):

struct sockaddr_in ;

2.bind函式

int bind(int sockfd, struct sockaddr* addr,socklen_t  addrlen)

引數sockfd

指定位址與哪個套接字繫結,這是乙個由之前的socket函式呼叫返回的套接字。呼叫bind的函式之後,該套接字與乙個相應的位址關聯,傳送到這個位址的資料可以通過這個套接字來讀取與使用。

引數addr

正如大多數socket介面一樣,核心不關心位址結構,當它複製或傳遞位址給驅動的時候,它依據這個值來確定需要複製多少資料。這已經成為socket介面中最常見的引數之一了。

引數addrlen

是引數addr的大小

3.listen函式

int listen(int sock, int backlog);

sock 為需要進入監聽狀態的套接字,backlog 為請求佇列的最大長度。

所謂被動監聽,是指當沒有客戶端請求時,套接字處於「睡眠」狀態,只有當接收到客戶端請求時,套接字才會被「喚醒」來響應請求。

4.accept函式

int accept(int sock, struct sockaddr *addr,socklen_t *addrlen);

sock 為伺服器端套接字,addr 為 sockaddr_in 結構體變數,addrlen 為引數 addr 的長度,可由 sizeof() 求得。

accept() 返回乙個新的套接字來和客戶端通訊,addr 儲存了客戶端的ip位址和埠號,而 sock 是伺服器端的套接字,大家注意區分。後面和客戶端通訊時,要使用這個新生成的套接字,而不是原來伺服器端的套接字。

二、具體程式設計實現

1.tcp-server

這是乙個普通的tcp伺服器,可以允許乙個客戶端進行連線

#include #include #include #include #include #include #include #define maxn_str 40

void usage(const char* proc)

int startup(char* ip,int port)

struct sockaddr_in local;

local.sin_family=af_inet;

local.sin_port=htons(port);

local.sin_addr.s_addr=inet_addr(ip);

int opt=1;

setsockopt(sock,sol_socket,so_reuseaddr,&opt,sizeof(opt));

if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)

if(listen(sock,5)<0)

return sock;

}int main(int argc,char* argv)

int listen_sock=startup(argv[1],atoi(argv[2]));

char buf[10240];

struct sockaddr_in client;

socklen_t len=sizeof(client);

while(1)

close(listen_sock);

printf("connect... ip is %s,port is %d\n ",inet_ntoa(client.sin_addr),ntohs(client.sin_port));

while(1)

else if(s==0)

else

}return 0;

}return 0;

}

2.tcp-server多程序版本

可以允許多個客戶端同時連線

#include #include #include #include #include #include #include #define maxn_str 40

void usage(const char* proc)

int startup(char* ip,int port)

struct sockaddr_in local;

local.sin_family=af_inet;

local.sin_port=htons(port);

local.sin_addr.s_addr=inet_addr(ip);

int opt=1;

setsockopt(sock,sol_socket,so_reuseaddr,&opt,sizeof(opt));

if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)

if(listen(sock,5)<0)

return sock;

}int main(int argc,char* argv)

int listen_sock=startup(argv[1],atoi(argv[2]));

char buf[1024];

struct sockaddr_in client;

socklen_t len=sizeof(client);

while(1)

printf("connect... ip is %s,port is %d \n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));

pid_t id=fork();

if(id>0)

else if(id==0)

else if(s == 0)

else

}return 0;

}else

}return 0;

}

3.tcp-server多執行緒版本

#include #include #include #include #include #include #include #include #include void usage(char* proc)

int startup(char* ip, int port)

struct sockaddr_in local;

local.sin_family = af_inet;

local.sin_port = htons(port);

local.sin_addr.s_addr = inet_addr(ip);

int opt = 1;

setsockopt(sock, sol_socket, so_reuseaddr, &opt, sizeof(opt));

if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)

if(listen(sock, 5) < 0)

return sock;

}void *handlerrequest(void* arg)

else

}}int main(int argc, char* argv)

int listen_sock = startup(argv[1], atoi(argv[2]));

struct sockaddr_in client;

socklen_t len = sizeof(client);

while(1)

printf("get a new connect, %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));

pthread_t id;

pthread_create(&id, null, handlerrequest, (void *)new_sock);

pthread_detach(id);

}return 0;

}

4.tcp-client客戶端部分

#include #include #include #include #include #include #include static void usage(const char* proc)

int main(int argc, char* argv)

int sock = socket(af_inet, sock_stream, 0);

if(sock < 0)

struct sockaddr_in remote;

remote.sin_family = af_inet;

remote.sin_port = htons(atoi(argv[2]));

remote.sin_addr.s_addr = inet_addr(argv[1]);

if(connect(sock, (struct sockaddr*)&remote, sizeof(remote)) < 0)

while(1)}}

return 0;

}

QT Socket程式設計 TCP Server

1 在 pro檔案中新增 qt network 2 在 中新增 qtcpserver m ptcpserver server tcp socket qtcpsocket m pconnectsocket client connect socket 初始化socket m ptcpserver new...

WIN網路程式設計 TCPServer

tcpserver.cpp檔案 include common initsock.h include cinitsock initsock 初始化winsock庫 int main 填充sockaddr in結構 sockaddr in sin sin.sin family af inet sin.s...

socket網路程式設計之TCP Server

include include include include dword winapi recvproc lpvoid lpparameter thread data struct recvparam void main if lobyte wsadata.wversion 1 hibyte ws...