SOCKET
一. TCP
1) 服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define ERROR_MSG(msg) do{\
fprintf(stderr, "line:%d: %s %s", __LINE__, __FILE__, __func__);\
perror(msg);\
}while(0)
#define IP "192.168.50.83"
#define PORT 6666
typedef struct {
int sockfd;
}socketInfo;
//发送线程
void *sendThreadHandler(void *arg) {
socketInfo *info = (socketInfo *)arg;
char buf[128] = "";
while(1) {
bzero(buf, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
//buf[strlen(buf)-1] = '\0';
int res = send(info->sockfd, buf, strlen(buf), 0);
if (res < 0) {
printf("发送失败 \n");
}
}
}
//接收线程
void *rcvThreadHandler(void *arg) {
socketInfo *info = (socketInfo *)arg;
char buf[128] = "";
ssize_t res = 0;
while(1) {
bzero(buf, sizeof(buf));
res = recv(info->sockfd, buf, sizeof(buf), 0);
if (res < 0) {
ERROR_MSG("recv");
exit(EXIT_SUCCESS);
} else if (0 == res) {
printf("客户端下线 \n");
exit(EXIT_SUCCESS);
}
printf("newfd = %d: %s\n", info->sockfd, buf);
}
}
int main(int argc, const char *argv[]) {
//1.创建流式套接字
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if (sfd < 0) {
ERROR_MSG("socket");
return -1;
}
//允许端口快速被重用
int reuse = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
ERROR_MSG("setsockopt");
return -1;
}
//2.绑定服务器的IP和端口
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
ERROR_MSG("bind");
return -1;
}
//3.将套接字设置为被动监听状态
if (listen(sfd, 128) < 0) {
ERROR_MSG("listen");
return -1;
}
//4.获取连接成功后的新的套接字文件描述符
struct sockaddr_in cin; //存储客户端的地址信息close(newfd);
socklen_t addrlen = sizeof(cin);
int newfd = accept(sfd, (struct sockaddr *)&cin, &addrlen);
if (newfd < 0) {
ERROR_MSG("accept");
return -1;
}
printf("客户端连接成功 newfd = %d, line = %d \n", newfd, __LINE__);
printf("客户端信息: family = %d, port = %d, add = %s \n",\
cin.sin_family, ntohs(cin.sin_port), inet_ntoa(cin.sin_addr));
//5. 接收
socketInfo i;
i.sockfd = newfd;
pthread_t tidr;
pthread_create(&tidr, NULL, rcvThreadHandler, &i);
//6. 发送
pthread_t tids;
pthread_create(&tids, NULL, sendThreadHandler, &i);
pthread_join(tids, NULL);
pthread_join(tidr, NULL);
//7. 关闭
close(newfd);
close(sfd);
return 0;
}
2)客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define ERROR_MSG(msg) do{\
fprintf(stderr, "line:%d: %s %s", __LINE__, __FILE__, __func__);\
perror(msg);\
}while(0)
#define IP "192.168.50.83"
#define PORT 6666
typedef struct {
int sockfd;
}socketInfo;
//发送线程
void *sendThreadHandler(void *arg) {
socketInfo *info = (socketInfo *)arg;
char buf[128] = "";
while(1) {
bzero(buf, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
//buf[strlen(buf)-1] = '\0';
int res = send(info->sockfd, buf, strlen(buf), 0);
if (res < 0) {
printf("发送失败 \n");
}
}
}
//接收线程
void *rcvThreadHandler(void *arg) {
socketInfo *info = (socketInfo *)arg;
char buf[128] = "";
ssize_t res = 0;
while(1) {
bzero(buf, sizeof(buf));
res = recv(info->sockfd, buf, sizeof(buf), 0);
if (res < 0) {
ERROR_MSG("recv");
exit(EXIT_SUCCESS);
} else if (0 == res) {
printf("服务器下线 \n");
exit(EXIT_SUCCESS);
}
printf("cfd = %d: %s\n", info->sockfd, buf);
}
}
int main(int argc, const char *argv[]) {
//1.创建流式套接字
int cfd = socket(AF_INET, SOCK_STREAM, 0);
if (cfd < 0) {
ERROR_MSG("socket");
return -1;
}
/*
//允许端口快速被重用
int reuse = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
ERROR_MSG("setsockopt");
return -1;
}
*/
//2.绑定服务器的IP和端口
/*
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
ERROR_MSG("bind");
return -1;
}
*/
//3. 连接
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(6666);
sin.sin_addr.s_addr = inet_addr(IP);
if (connect(cfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
ERROR_MSG("connect:");
return -1;
}
printf("连接成功 \n");
//5. 接收
socketInfo i;
i.sockfd = cfd;
pthread_t tidr;
pthread_create(&tidr, NULL, rcvThreadHandler, &i);
//6. 发送
pthread_t tids;
pthread_create(&tids, NULL, sendThreadHandler, &i);
pthread_join(tids, NULL);
pthread_join(tidr, NULL);
//7. 关闭
close(cfd);
return 0;
}
TPC结果展示:
2. UDP
1) 服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define ERROR_MSG(msg) do{\
fprintf(stderr, "line:%d: %s %s", __LINE__, __FILE__, __func__);\
perror(msg);\
}while(0)
#define IP "192.168.50.83"
#define PORT 6666
int main(int argc, const char *argv[]) {
//创建报式套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0) {
ERROR_MSG("socket");
return -1;
}
printf("创建socket成功 \n");
//绑定地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
ERROR_MSG("bind");
return -1;
}
printf("绑定成功 \n");
while(1) {
//接收数据
char buf[128] = "";
struct sockaddr addr;
int addrlen = sizeof(addr);
if(recvfrom(sfd, buf, sizeof(buf), 0, &addr, &addrlen) < 0) {
ERROR_MSG("recvfrom:");
return -1;
}
printf("接收到的数据是:%s \n", buf);
//发送数据
strcat(buf, "*_*");
if (sendto(sfd, buf, strlen(buf), 0, &addr, addrlen) < 0) {
ERROR_MSG("sendto:");
return -1;
}
}
//关闭
close(sfd);
return 0;
}
2) 客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define ERROR_MSG(msg) do{\
fprintf(stderr, "line:%d: %s %s", __LINE__, __FILE__, __func__);\
perror(msg);\
}while(0)
#define IP "192.168.50.83"
#define PORT 6666
//接收线程
void *rcvHandler(void *arg) {
int *sfd = (int *)arg;
char buf[128] = "";
while(1) {
if(recv(*sfd, buf, sizeof(buf), 0) < 0) {
ERROR_MSG("recvfrom:");
exit(EXIT_SUCCESS);
}
printf("接收到的数据是:%s \n", buf);
}
}
//发送到服务器线程
void *sndHandler(void *arg) {
int *sfd = (int *)arg;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(IP);
int addrlen = sizeof(addr);
char buf[128] = "";
while(1) {
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = 0;
if (sendto(*sfd, buf, strlen(buf), 0, (struct sockaddr *)&addr, addrlen) < 0) {
ERROR_MSG("sendto:");
exit(EXIT_SUCCESS);
}
}
}
int main(int argc, const char *argv[]) {
//创建报式套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0) {
ERROR_MSG("socket");
return -1;
}
printf("创建socket成功 \n");
pthread_t rcvTid, sndTid;
pthread_create(&rcvTid, NULL, rcvHandler, &sfd);
pthread_create(&sndTid, NULL, sndHandler, &sfd);
pthread_join(rcvTid, NULL);
pthread_join(sndTid, NULL);
//关闭
close(sfd);
return 0;
}
结果展示