Window TCP 服務(wù)端
- 注意事項(xiàng)
- 引入windows.h頭文件
- 引入ws2_32.lib網(wǎng)絡(luò)庫(kù)
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void createTcpSocket()
{
//初始化Socket
WSADATA ws;
WSAStartup(MAKEWORD(2,2),&ws);
/**
創(chuàng)建socket
SOCKET socket(int af,int type,int protocal);
af 表示一個(gè)網(wǎng)絡(luò)地址類型机蔗,通常為AF_INET吹零,表示套接字在Internet域中通信爵嗅。
type:表示套接字類型。如果為SOCK_STREAM蘑辑,表示流式套接字,如果為SOCK_DGRAM,表示數(shù)據(jù)報(bào)套接字科乎。
protocal:表示網(wǎng)絡(luò)協(xié)議,通常為0前酿,表示采用TCP/IP協(xié)議患雏。
**/
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock==-1){
printf("create socket failed!\n");
return -1;
}
short port=9800;
//sockaddr_in 描述服務(wù)端描述,如端口罢维、IP淹仑、地址族
sockaddr_in saddr;
saddr.sin_family = AF_INET; //地址族
//htons函數(shù)將本地字節(jié)序轉(zhuǎn)網(wǎng)絡(luò)字節(jié)序
saddr.sin_port = htons(port); //設(shè)置端口號(hào)
//綁定IP地址,0表示所有網(wǎng)卡都作為TCP監(jiān)聽(tīng)。
saddr.sin_addr.s_addr = htonl(0);
//綁定端口等信息
if(::bind(sock,(sockaddr*)&saddr,sizeof(saddr))!=0) {
//綁定端口失敗
printf("bind port %d failed!\n",port);
return -2;
}
printf("bind port %d success!\n",port)
//告訴操作系統(tǒng)可以監(jiān)聽(tīng)客戶端的連接
/**
int listen(int sockfd, int backlog);
第一個(gè)參數(shù)sockfd為創(chuàng)建socket返回的文件描述符肺孵。
第二個(gè)參數(shù)backlog為建立好連接處于ESTABLISHED狀態(tài)的隊(duì)列的長(zhǎng)度
**/
listen(sock,10);
//讀取客戶端的連接信息
sockaddr_in caddr;
socklen_t len=0;
int clientSock=accept(sock,(sockaddr*)&caddr,&len);
printf("accept client %d\n",clientSock);
//inet_ntoa 函數(shù)是將結(jié)構(gòu)轉(zhuǎn)ip字符串
char *ip=inet_ntoa(caddr.sin_addr);
unsigned short cport=ntohs(caddr.sin_port);
//讀取客戶端數(shù)據(jù)
char buf[1024]={0};
int recvlen= recv(clientSock,buf,sizeof(buf)-1,0);
//發(fā)生消息
send(clientSock,"ok",3,0);
//關(guān)閉socket
closesocket(sock);
}
Linux TCP 服務(wù)端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
//atoi
#include <stdlib.h>
//htonl
#include <arpa/inet.h>
#include <string.h>
void createSocket()
{
/**
創(chuàng)建socket
SOCKET socket(int af,int type,int protocal);
af 表示一個(gè)網(wǎng)絡(luò)地址類型匀借,通常為AF_INET,表示套接字在Internet域中通信悬槽。
type:表示套接字類型怀吻。如果為SOCK_STREAM,表示流式套接字初婆,如果為SOCK_DGRAM蓬坡,表示數(shù)據(jù)報(bào)套接字。
protocal:表示網(wǎng)絡(luò)協(xié)議磅叛,通常為0屑咳,表示采用TCP/IP協(xié)議。
**/
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock==-1){
printf("create socket failed!\n");
return -1;
}
short port=9800;
//sockaddr_in 描述服務(wù)端描述弊琴,如端口兆龙、IP、地址族
sockaddr_in saddr;
saddr.sin_family = AF_INET; //地址族
//htons函數(shù)將本地字節(jié)序轉(zhuǎn)網(wǎng)絡(luò)字節(jié)序
saddr.sin_port = htons(port); //設(shè)置端口號(hào)
//綁定IP地址,0表示所有網(wǎng)卡都作為TCP監(jiān)聽(tīng)敲董。
saddr.sin_addr.s_addr = htonl(0);
//綁定端口等信息
if(::bind(sock,(sockaddr*)&saddr,sizeof(saddr))!=0) {
//綁定端口失敗
printf("bind port %d failed!\n",port);
return -2;
}
printf("bind port %d success!\n",port)
//告訴操作系統(tǒng)可以監(jiān)聽(tīng)客戶端的連接
/**
int listen(int sockfd, int backlog);
第一個(gè)參數(shù)sockfd為創(chuàng)建socket返回的文件描述符紫皇。
第二個(gè)參數(shù)backlog為建立好連接處于ESTABLISHED狀態(tài)的隊(duì)列的長(zhǎng)度
**/
listen(sock,10);
//讀取客戶端的連接信息
sockaddr_in caddr;
socklen_t len=0;
int clientSock=accept(sock,(sockaddr*)&caddr,&len);
printf("accept client %d\n",clientSock);
//inet_ntoa 函數(shù)是將結(jié)構(gòu)轉(zhuǎn)ip字符串
char *ip=inet_ntoa(caddr.sin_addr);
unsigned short cport=ntohs(caddr.sin_port);
//讀取客戶端數(shù)據(jù)
char buf[1024]={0};
int recvlen= recv(clientSock,buf,sizeof(buf)-1,0);
//發(fā)生消息
send(clientSock,"ok",3,0);
//關(guān)閉socket
close(sock);
}
C++線程
#include <thread>
class TcpThread{
public:
void Main()
{
}
int clientSock;
}
void createThread()
{
TcpThread *th=new TcpThread();
//創(chuàng)建線程
thread sth(&TcpThread::Main,th);
//拆分子線程與主線程關(guān)系
sth.detach();
}
Makefile
tcpserver:main.cpp
g++ main.cpp -o tcpserver -std=c++11 -lpthread