TCP实现局域网通信
TCP客户端通信步骤:
1:创建套接字 sockfd = socket(AF_INET ,SOCK_STREAM ,0);
2:填写服务器结构体信息
struct sockaddr_in serveraddr;
socklen_t addrlen = sizeof(serveraddr);
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
其中服务器信息结构体要用sockaddr_in创建
3:发送客户端连接请求
connect(sockfd, (struct sockaddr *)&serveraddr,addrlen);
注意服务器信息结构体要进行强制类型转换
4:进行通信
recv(sockfd, buf1, 128, 0);
send(sockfd, buf, 128, 0);
注意send和recv可以设置阻塞和非阻塞 recv默认阻塞
其中可以通过创建进程和线程实现接收和发送
5:关闭套接字
TCP服务器通信步骤:
1:创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
2:将套接字和服务器信息结构体绑定
struct sockaddr_in serveraddr, clientaddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
bind(sockfd, (struct sockaddr *)&serveraddr, addrlen);
3:将套接字设置为监听状态
listen(sockfd, 5)
4:阻塞等待客户端连接请求
acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)
5:进行通信
6:关闭套接字
关闭监听套接字导致服务器无法建立新连接,但不影响已建立连接
关闭accept返回的套接字代表该套接字的连接关闭,不影响服务器监听
实现TCP并发服务器
客户端代码:client_Ancy.c
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
z
char buf1[128] = "";
pthread_t thread;
int sockfd;
char ip[] = "180.201.00.00";
char port[] = "8080";
void thread_do(){
while(1){
fgets(buf,128,stdin);
buf[strlen(buf) - 1] = '\0';
send(sockfd, buf, 128, 0);
}
}
int main(int argc, char const *argv[])
{
if (argc<3){
printf("Usage: %s [ip] [port]\n", argv[0]);
exit(1);
}
sockfd = socket(AF_INET ,SOCK_STREAM ,0);
struct sockaddr_in serveraddr;
socklen_t addrlen = sizeof(serveraddr);
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
connect(sockfd, (struct sockaddr *)&serveraddr,addrlen);
pthread_create(&thread, NULL, (void *)&thread_do,NULL);
while(1){
memset(buf1,0,128);
recv(sockfd, buf1, 128, 0);
printf("recv:%s\n",buf1);
}
close(sockfd);
}
多进程实现服务器代码:server_Ancy.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <signal.h>
#define N 128
#define ERR_LOG(errmsg) do{\
perror(errmsg);\
exit(1);\
}while(0)
void handler(int sig)
{
wait(NULL);
}
int main(int argc, char const *argv[])
{
if(argc < 3)
{
fprintf(stderr, "Usage: %s <server_ip> <server_port>\n", argv[0]);
exit(1);
}
int sockfd, acceptfd;
struct sockaddr_in serveraddr, clientaddr;
socklen_t addrlen = sizeof(serveraddr);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
ERR_LOG("fail to socket");
}
int on = 1;
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
{
ERR_LOG("fail to setsockopt");
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0)
{
ERR_LOG("fail to bind");
}
if(listen(sockfd, 5) < 0)
{
ERR_LOG("fail to listen");
}
signal(SIGCHLD, handler);
while(1)
{
if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0)
{
ERR_LOG("fail to accept");
}
printf("%s -- %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
pid_t pid;
if((pid = fork()) < 0)
{
ERR_LOG("fail to fork");
}
else if(pid > 0)
{
}
else
{
char buf[N] = "";
ssize_t bytes;
while (1)
{
if((bytes = recv(acceptfd, buf, N, 0)) < 0)
{
ERR_LOG("fail to recv");
}
else if(bytes == 0)
{
printf("The client quited\n");
exit(0);
}
if(strncmp(buf, "quit", 4) == 0)
{
exit(0);
}
printf("from client: %s\n", buf);
strcat(buf, " ^_^");
if(send(acceptfd, buf, N, 0) < 0)
{
ERR_LOG("fail to send");
}
}
}
}
return 0;
}
多线程实现服务器代码:server_Ancy.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#define N 128
#define ERR_LOG(errmsg) do{\
perror(errmsg);\
exit(1);\
}while(0)
typedef struct{
struct sockaddr_in addr;
int acceptfd;
}MSG;
void *pthread_fun(void *arg)
{
char buf[N] = "";
ssize_t bytes;
MSG msg = *(MSG *)arg;
while (1)
{
if((bytes = recv(msg.acceptfd, buf, N, 0)) < 0)
{
ERR_LOG("fail to recv");
}
else if(bytes == 0)
{
printf("The client quited\n");
pthread_exit(NULL);
}
if(strncmp(buf, "quit", 4) == 0)
{
printf("The client quited\n");
pthread_exit(NULL);
}
printf("[%s - %d]: %s\n", inet_ntoa(msg.addr.sin_addr), ntohs(msg.addr.sin_port), buf);
strcat(buf, " ^_^");
if(send(msg.acceptfd, buf, N, 0) < 0)
{
ERR_LOG("fail to send");
}
}
}
int main(int argc, char const *argv[])
{
if(argc < 3)
{
fprintf(stderr, "Usage: %s <server_ip> <server_port>\n", argv[0]);
exit(1);
}
int sockfd, acceptfd;
struct sockaddr_in serveraddr, clientaddr;
socklen_t addrlen = sizeof(serveraddr);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
ERR_LOG("fail to socket");
}
int on = 1;
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
{
ERR_LOG("fail to setsockopt");
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0)
{
ERR_LOG("fail to bind");
}
if(listen(sockfd, 5) < 0)
{
ERR_LOG("fail to listen");
}
while(1)
{
if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0)
{
ERR_LOG("fail to accept");
}
MSG msg;
msg.addr = clientaddr;
msg.acceptfd = acceptfd;
pthread_t thread;
if(pthread_create(&thread, NULL, pthread_fun, &msg) != 0)
{
ERR_LOG("fail to pthread_create");
}
pthread_detach(thread);
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)